Java Random Notes
Until I find time to get more organized, here are a number of miscellaneous
notes assembled when I find answers to Java questions and don't want to have to
go looking for them again.
Some defintions from Javaland
EAR
E nterprise ar chive . An archive containing the
enterprise-level Java bean modules.
JAR
J ava ar chive . Collection of .class files
compiled from .java files plus resources (like properties
files) and libraries (more .jar files).
WAR
W eb ar chive . Collection of JSPs (.jsp
files), .html files, even graphics and other files necessary
to the web application.
next definition
x .
Utility methods...
A collection of utility methods isn't OOP (with a capital OOP). These methods
should be static since their behaviour is not dependent on any specific
instance of attributes.
Use of static ...
A static variable in a class becomes a single instance for all
instantiations of objects of that type. If changed by one, it's changed for all
objects. static final will ensure its inability to be modified.
Declare immutable constants as static final . This guards against
inadvertant modification and permits the compiler to perform optimizations in
the use of those values.
Identifier case...
Use camel-back, lower-case initial in the names of methods and non-constant
variables.
Width of characters...
A char cannot be safely converted to byte .
Flow-control...
Never use exceptions for flow-control.
Use of .class ...
String className = ASConfig.class.getName();
Given <class-type> .class. <method>
.class gets the Class object for the class-type and calls the indicated
method. In the sample above, the class name is returned.
See
http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.8.2
Accessors and mutators
..are formal names for getters and setters.
Conversions
int to String
int x = 99;
String X = Integer.toString( x );
// or
String X = "" + x;
JUnit testing
See junit.html .
Integers in Java
Type
Size
Range
name
bytes
bits
minimum
maximum
byte
1
8
-128
+127
short
2
16
-32,768
+32,767
int
4
32
-2,147,483,648
+2,147,483,647
long
8
64
-9,223,372,036,854,775,808
+9,223,372,036,854,775,807
Instance variable instantiation
Consider the following class and subclass which illustrate a bizarre point of
instance variable initialization. It might be a long time if ever someone
actually suffers from this problem, but it makes a useful observation on
initialization. The explanation here is a bit awkward and over-stated, but
clear, I think.
class Abc
{
public Abc( Object o )
{
assignValue( o );
}
public void assignValue( Object o )
{
// do nothing...
}
}
public class Test extends Abc
{
public Object x = null;
public Test( Object o )
{
super( o );
}
public void assignValue(Object o)
{
x = o;
System.out.println( "x in assignValue: " + x );
}
public static void main( String args[] ) throws CloneNotSupportedException
{
Test t = new Test( "Test" );
System.out.println( "t: " + t.x );
}
}
Output:
x in assignValue: Test
t: null
The output happens because the initialization:
public Object x = null;
executes after the constructor. So...
x = 0;
gets overwritten by
public Object x = null;
The secret is that the compiler in fact arranges to call the explicitly invoked
superclass constructor before the (local) constructor will get executed.
The initializations done as part of the class instance variable declarations
are part of and occur before the (local) construction process. In our example,
they occur implicitly before the statements in the (subclass) constructor, with
the exception of the superclass constructor invocation as noted.
Therefore, execution order is not straightforward as it is in C. Hence, here
the null initialization runs after the local class' call of its superclass
constructor. The compiler in essence absorbs the
super( o );
statement and runs it before any other constructor statements as well as even
before applying the initializations stated in the instance variable
declarations.
See
http://forums.sun.com/thread.jspa?forumID=31&threadID=5260093 .
I/O
Here's a good site for sample code:
http://www.exampledepot.com/egs/java.io/pkg.html
See also sample code in com.etretatlogiciels.samples.fileio.
The finally clause
Use this to close streams, file handles, database connections, etc.
StreamUtils.close() is your short-hand friend for the first case.
Properties properties = new Properties();
FileInputStream is = null;
try
{
is = new FileInputStream( path );
properties.load( is );
}
catch( FileNotFoundException e )
{
System.out.println( e.getMessage() );
}
catch( IOException e )
{
System.out.println( e.getMessage() );
}
finally
{
StreamUtils.close( is );
}
PipeStream
Research this class for transforming an input stream into an output stream and
vice-versa.
Reader versus Stream
In Java I/O, a file or other device may be opened on a stream and somewhere in
the layer cake that wraps the device may be a reader. A reader augments a
stream in that it deals with characters (UTF-8, etc.) rather than bytes.
Synchronization in Java
This is not an exhaustive treatment of concurrency solutions in Java. It is a
simple treatment, from a C programmer's mentality, of the Java keyword,
synchronized . Java uses this keyword in two ways.
Synchronized blocks
The synchronized keyword is used to synchronize a block of
executable statements by referring to an object. This object becomes like a
mutex in procedural programming languages: executing all other blocks with
reference to object is serialized:
Object object = new Object();
synchronized( object )
{
do something with object ;
}
How it works
On its face, object is not any kind of mutex, condition variable,
reader-writer lock, barrier or other synchronization primitive that you would
expect to declare in a procedural language to manage your protected data in
parallel. But in fact, every Java object contains a lock within itself. This
lock is formally referred to as a monitor . When the compiler sees
synchronized in this situation, it generates code to use the
object's monitor.
Synchronized methods
The synchronized keyword is also used to synchronize goings on in
a method. This is also like controlling execution of the method based on a
mutex, but the object is implied this rather than explicit.
synchronized void makeSomeoneHappy ()
{
do something to make someone happy with several objects;
}
All synchronized methods share the same mutex (this , as noted).
The above is directly equivalent to:
void makeSomeoneHappy ()
{
synchronized( this )
{
do something to make someone happy with several objects;
}
}
Watch out!
A private member variable in a class isn't safe unless all methods touching it
are explicitly synchronized. A public member variable would practically never
be safe. In the following class, x is safe, but y is not even
though their manipulating methods are synchronized.
public class TwoCounters
{
private int x = 0;
public int y = 0;
public synchronized getX () { return this.x ; }
public synchronized incX () { this.x ++; }
public synchronized zeroX (){ this.x = 0; }
public synchronized getY () { return this.y ; }
public synchronized incY () { this.y ++; }
public synchronized zeroY (){ this.y = 0; }
}
This is because code outside this class can freely access y whereas an
attempt to access x would be rebuffed by the compiler:
TwoCounters counter = new TwoCounters ();
counter.y = 99; PASSES COMPILER, BUT A BAD IDEA!
counter.x = 99; COMPILATION ERROR!
The distinction between the two methods of synchronization just contrasted is
that in the second case, no actual, explicit object is needed in writing the
code to perform serialization. There is no need to create object .
Instead, the implied object, this , is used.
(Yup, this is absolutely the first time in over a decade of writing HTML
that I have used the <blink> tag: very annoying, isn't it?)
Deadlocking
Between correctly synchronized methods in diverse classes deadlocks can easily
occur, in particular, the ABBA . The following is the scenario.
Thread A enters a synchronized method for class Foo . It holds the
monitor for Foo 's this . Let's say that thread A
blocks momentarily on some I/O operation.
Thread B enters a synchronized method for class Bar . It holds the
monitor for Bar 's this . Thread B also knows about
the same instance of Foo as thread A and attempts to enter one
of Foo 's synchronized methods. Foo 's monitor is
contested because thread A already has it.
Thread A wakes up from its I/O operation and, having a reference to the
instance of Bar that thread B already has locked, decides to
attempt to enter one of Bar 's synchronized methods.
Thread A is blocked on a monitor held by thread B and thread B is blocked
on a monitor held by thread A.
This sort of nightmare is best prevented by careful design. The temptation by
bad engineers in a procedural language might be to test whether a lock is going
to be contested before attempting to use it and, indeed, it is sometimes
impossible to do otherwise. However, all efforts to design logic to avoid doing
this should be made. Moreover, as noted next, it was not possible prior to Java
1.5 to perform a try-lock .
More traditional locking in Java
Starting (only) in Java 1.5, a new interface, Lock , is provided to
mimic not only mutexes in use in other, especially procedural languages, but
also try-locking mutexes, condition variables and reader-writer locks.
Without giving an implementation here (because that is how one chooses to
implement a mutex versus a condition variable versus a reader-writer or other
kind of lock), this example shows how it is used:
Lock l = new ...();
l .lock();
try
{
do something with resources controlled by lock l ;
}
finally
{
l .unlock();
}
This usage is unsurprising and recognizable to any C programmer. The reason for
this to exist (finally) in Java is that it gives greater flexibility (if also
imposing the inelegant coding duty of maintaining the lock just as in C).
Using synchronized does not give you the finer control to do
something else in the case the object is contested: you are blocked on
permanently on the object (explicit object or implicit
this ) until the thread that has it locked yields it. Hence the
utility of this new interface.
Managed beans (and JSF)
In Java, a managed bean is a resource running in the Java virtual machine (JVM)
used for getting and setting application configuration (pull); for collecting
statistics (also a pull operation), e.g.: performance, resource usage,
problems; and notifying events (push), e.g.: faults and state changes.
A good article with much better examples on this topic than those below can be
found
here .
A standard managed bean often implements a business interface containing
setters and getters for the attributes and the operations (or methods). There
are other sorts of managed beans.
The managed bean is also involved in inversion of control (dependency
injection) and the POJO (plain-old Java object).
Managed beans and JavaServer Faces (JSF)
Before server-side Java development became the norm, developers managed all of
their classes manually. Contemporarily, Java server "containers" (like Tomcat)
have become responsible for running applications and POJOs have come back into
popularity because they are so simple (as compared to Enterprise JavaBeans) and
useful for performing dependency injection (formerly called "inversion of
control" or IoC). The JSF managed bean facility is also an IoC framework that
makes management of JavaBeans or POJOs easy for JSF developers.
Control of instantiation
The first item of business for IoC is being able to manage instantiation of
Java objects. Originally, this was done in a page using JSP's
<jsp:usebean> that instantiated a bean for a specified scope.
This is now done using faces-config.xml and any Java class with a
no-argument constructor may be registered. Imagine a POJO thus:
public class TemperatureConverter
{
private double celsius = 0.0;
private double fahrenheit = 0.0;
private boolean initial = true;
public double getCelsius() { return celsius; }
public void setCelsius( double celsius ) { this.celsius = celsius; }
public double getFahrenheit() { return fahrenheit; }
public boolean getInitial() { return initial; }
public String reset()
{
initial = true;
fahrenheit = 0;
celsius = 0;
return "reset";
}
public String celsiusToFahrenheit()
{
initial = false;
fahrenheit = ( celsius * 9 / 5 ) + 32;
return "calculated";
}
}
The dead give-away that this is a bean is:
no-argument constructor
getter(s) and setter(s)
In faces-config.xml , the bean, which is otherwise coded as above (no
surprise) and included in the application as a simple Java object (POJO), is
registered thus:
<managed-bean>
<managed-bean-name> temperatureConverter </managed-bean-name>
<managed-bean-class> mypackage.TemperatureConverter </managed-bean-class>
<managed-bean-scope> session </managed-bean-scope>
<managed-property>
<property-name> celsius </property-name>
<value> 37.0 </value>
</managed-property>
<managed-property>
<property-name> fahrenheit </property-name>
<value> 98.6 </value>
</managed-property>
</managed-bean>
temperatureConverter is sort of arbitrarily named, but follows a common
convention of dropping the first letter of the class to lower-case (since it is
used in JSF as an indentifier).
In addition, the implicit "properties" of the bean, celsius and
fahrenheit can be the target of initialization in the same
faces-config.xml file as shown in the example above where the imaginary
Celsius-to-Fahrenheit calculator will start up set at the temperature of a
human body.
faces-config.xml is found in the typical web application at
WEB-INF . For example, in Eclipse by default this is
project-name/WebContent/WEB-INF/faces-config.xml . In the example above,
the Java code is located at
project-name/src/mypackage/TemperatureConverter.java .
Dependency handling
The ability to handle interdependence between Java objects is another
requirement of IoC. JSF doesn't handle cyclical dependencies, but managed beans
can refer to each other using expression language.
Life-cycle support
Another requirement of IoC is support of the life-cycle of, say, HTTP requests
and other durations. Hence, JSF defines various levels of...
none (or "no scope")
request
session
application
...granularity. No (none ) granularity is when the bean has no scope, is
created on the fly and whenever needed. The request is the bean having
scope (and managed properties and values) only for the duration of an HTTP
request. By session , the bean properties and values remain in effect
(modified as many times or none) for an arbitrary length of time or operations
as conceived by the developer, for example, a shopping cart that dies after a
user has ordered or left the web site. Finally, the application -scoped
bean exists while the application is up and running, for example a database
connection.
Configuration support
The primary task of JSF is to present a web interface to a client that is
predictably and automatically synchronized with one or a set of managed objects
without extensive, spaghetti-like and difficult coding.
System properties
Much is configurable in Java and:
String property = System.getProperty( property-name );
...is how a property is got. There are three ways they are set.
First, Sun sets them, like java.io.tmpdir , predefined, in its JRE.
Other JREs do too and, from platform to platform, there is sometimes the
tiniest bit of non-conformance.
Second, you can set them yourself using the command line:
# java -Dhow.i.feel=blue MyClass
Last, you can set them programmatically:
String libraries = System.getProperty( "java.library.path" );
if( libraries != null && libraries.length() != 0 )
libraries += ":" + "/home/russ/dev/libs";
else
libraries = "/home/russ/dev/libs";
System.setProperty( "java.library.path", libraries );
File.createTempFile()
A temporary file is created in java.io.tmpdir :
File f = File.createTempFile( "fun", ".poo" );
System.out.println( "Just created file "
+ f.getName()
+ " in directory "
+ System.getProperty( "java.io.tmpdir" )
);
The ternary operator
The ternary operator in Java is problematic, having trouble with mixed,
ambiguous or unclear typing in places where humans do not.
In the example, a compile-time error is generated.
In order to force understanding on the compiler, use parentheses as shown in
the subsequent line. This forces evaluation of the expression before settling
on what type is its result.
Type mismatch: cannot convert from String to boolean.
Double x = 9.0;
System.out.println( "This is a " + ( x == 9.9 ) ? "test" : "cat" + " of the Emergency Broadcast System" );
/* fixed: */
System.out.println( "This is a " + ( ( x == 9.9 ) ? "test" : "cat" ) + " of the Emergency Broadcast System" );
Viewing the contents of a JAR
Dump the particulars including class list for a JAR by
russ@taliesin:~/dev/downloads/myfaces-core-1.2.8/lib> tar tf myfaces-impl-1.2.8.jar
META-INF/
META-INF/MANIFEST.MF
META-INF/services/
javax/
javax/faces/
org/
org/apache/
org/apache/myfaces/
org/apache/myfaces/event/
org/apache/myfaces/taglib/
org/apache/myfaces/taglib/core/
org/apache/myfaces/taglib/html/
org/apache/myfaces/convert/
org/apache/myfaces/portlet/
.
.
.
META-INF/NOTICE.txt
META-INF/standard-faces-config.xml
META-INF/myfaces_core.tld
META-INF/myfaces_html.tld
META-INF/LICENSE.txt
META-INF/myfaces-metadata.xml
javax/faces/Messages_pl.properties
javax/faces/Messages_ru.properties
javax/faces/Messages_ja.properties
javax/faces/Messages_mt.properties
javax/faces/Messages_it.properties
javax/faces/Messages_ca.properties
javax/faces/Messages.properties
javax/faces/Messages_en.properties
.
.
.
org/apache/myfaces/taglib/core/ValidateDoubleRangeTag.class
org/apache/myfaces/taglib/core/SetPropertyActionListenerTag.class
org/apache/myfaces/taglib/core/LoadBundleTag.class
org/apache/myfaces/taglib/core/ConvertNumberTag.class
org/apache/myfaces/taglib/core/PhaseListenerTag$BindingPhaseListener.class
org/apache/myfaces/taglib/core/ValidatorImplTag.class
org/apache/myfaces/taglib/core/SubviewTag.class
org/apache/myfaces/taglib/core/GenericListenerTag.class
org/apache/myfaces/taglib/core/ConverterImplTag.class
org/apache/myfaces/taglib/core/LoadBundleTag$BundleMap.class
org/apache/myfaces/taglib/core/SelectItemTag.class
org/apache/myfaces/taglib/core/ActionListenerTag.class
org/apache/myfaces/taglib/core/GenericMinMaxValidatorTag.class
org/apache/myfaces/taglib/core/DelegateConverter.class
org/apache/myfaces/taglib/core/ConvertDateTimeTag.class
org/apache/myfaces/taglib/core/SelectItemsTag.class
org/apache/myfaces/taglib/core/VerbatimTag.class
.
.
.
org/apache/myfaces/webapp/StartupServletContextListener.class
.
.
.
org/apache/myfaces/application/jsp/ViewResponseWrapper$WrappedServletOutputStream.class
org/apache/myfaces/application/MyfacesStateManager.class
org/apache/myfaces/application/TreeStructureManager$TreeStructComponent.class
org/apache/myfaces/application/ApplicationFactoryImpl.class
org/apache/myfaces/application/DefaultViewHandlerSupport.class
org/apache/myfaces/application/ActionListenerImpl.class
META-INF/maven/
META-INF/maven/org.apache.myfaces.core/
META-INF/maven/org.apache.myfaces.core/myfaces-impl/
META-INF/maven/org.apache.myfaces.core/myfaces-impl/pom.xml
META-INF/maven/org.apache.myfaces.core/myfaces-impl/pom.properties