2008/09/03

Simple tip: Inject the nested class in Spring context

It's a simple tip and is not mentioned in Spring reference docs:

When you want create a bean in Spring which is a nested class of some owner class, use the "$" to separate the owner class name and the nested class name like following example:

<bean class="org.balah.OwnerClass$NestedClass"
.....

Don't use the convention like "org.balah.OwnerClass.NestedClass" that is used in the source code usually. Because the Spring will use Class.forName() similar mechanism to find the class specified in the bean definition. As you use the Class.forName() to load a nested class, always use "$" to let the classloader locate the exact class file from your classpathes. The "." sperated convention just confused the class resolver anf finally throw a ClassNotFoundException.

2008/04/24

Java7 new features: Personal View

Ref: The incoming Java 7 new features

All about just one thing: Java is becoming a platform and heavier and heavier version by version.Losing its very authentic and original simple beauty purely from language perspective.

Actually all the ideas are not quite new or very original innovative, they have already appeared in various libraries, components, frameworks and products. Sun is just collecting and refurbishing those ideas in name of JSR process then put them in its own JDK's shoes. Afterwards, MS will borrow the ideas but make it much easier to use in its monolithic .NET tools than diverted java tools world.

However, it's still a good news that the new changes on the heavier new "JAVA platform" will definitely drive the success of simpler and straightforward emerging dynamic 2G languages on top of Java, such as Groovy, which is just copying the same story Java replacing C/C++/Delphi 10 years ago!

Let's see.

Inter-thread coordination: wait, notify and interrupt

Just a sample code to test the inter-thread coordinating by using the object's wait and notify methods.

public class TestWaitAndNotify {
private final Object event = new Object(); private final Task1 task1 = new Task1(); private final Task2 task2 = new Task2(); private boolean stop; public TestWaitAndNotify() {
stop = false;
} public static void main(String[] args) throws InterruptedException {
TestWaitAndNotify twan = new TestWaitAndNotify(); twan.doIt();
} void doIt() throws InterruptedException {
task2.start(); task1.start(); stop = true; System.out.println("main:t [try to stop]"); synchronized (event){
System.out.println("main:t [notify all waiting threads]"); event.notifyAll();
} System.out.println("main:t [quit]");
} class Task1 extends Thread{
public void run(){
synchronized (event){
System.out.println("task1 running."); while(!stop){
System.out.println(">>>>>>>>task1 did"); event.notifyAll(); try {
System.out.println("task1 waiting."); event.wait(0); System.out.println("task1 wake");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
} System.out.println("task1 quit");
}
}
} class Task2 extends Thread{
public void run(){ synchronized (event){
System.out.println("Task2 running."); while(!stop){
try {
//Thread.sleep(10000); System.out.println("task2 waiting."); event.wait(0); System.out.println("task2 wake");
} catch (InterruptedException e) {
e.printStackTrace();
} System.out.println("<<<<<<<task2 did"); event.notifyAll();
} System.out.println("task2 quit");
} }
}
}
Conclusion:
  1. The order of threads starting is important in order to make sure the threads are waiting and notifying in sequence per our expectation.
  2. One object could be used as an event/signal to coordinate the threads behaviors by using wait and notify combination.
  3. Don't swallow or ignore the InterruptedException as you usually will do. Try to handle it properly, because someone might try to stop the blocking thread by interrupt it. Especially you are doing some common library which might be called by various unknown classes in various unknown conditions. Ignore it in your codes might cause other guy's attempts fail.
  4. Gracefully shutting down a thread by using an central control flag. However, a control thread or the main thread should try to call the coordinating object's notifyall before quit itself in order to wake up all the waiting threads and let them have a chance to shutdown gracefully.
  5. You can not always assume the call to the interrupt method of a blocking thread will work as your wish if you try to wake up it and let it quit. The probable failure case is:
    • If the blocking of thread is caused by waiting for the monitor of a synchronized method, it can not release the lock. However, if it's the case that the thread is waiting for a synchronized object, it's possible the interrupt will release the lock.
    • InterruptedException ignored by any codes is running in the thread when its interrupt is called.

2008/04/22

Incoming new Java 7 Featuers

Alex Miller has an excellent summarize of the new Java 7 Featuers:

Improved Modularity Support (superpackages)

   1. superpackage example.bar.lib {  
2.
3. // member packages
4. member package example.bar.lib;
5.
6. // member superpackages
7. member superpackage example.bar.lib.net, example.bar.lib.xml;
8.
9. // list of exported types
10. export example.bar.lib.Table;
11.
12. export superpackage example.bar.lib.net;
13. }

Java Module System
A distribution format and a repository for collections of Java code and related resources. It also defines the discovery, loading, and integrity mechanisms at runtime. Defines a new deployment archive called a JAM (Java Module). The Java Module is a JAR file that contains other JARs, resources, and metadata. JAMs can specify which portions of the module are public and which are hidden. JAMs can specify dependencies on other modules.

Java Kernel
Implement Java as a small kernel, then load the rest of the platform and libraries as needed, with the goal of reducing startup time, memory footprint, installation, etc. In the past this has also been referred to as “Java Browser Edition”.

NIO2
APIs for filesystem access, scalable asynchronous I/O operations, socket-channel binding and configuration, and multicast datagrams.

Date and Time API
A new and improved date and time API for Java. The main goal is to build upon the lessons learned from the first two APIs (Date and Calendar) in Java SE, providing a more advanced and comprehensive model for date and time manipulation.

Units and Quantities
one or more Java packages for the programmatic handling of physical quantities and their expression as numbers of units.

JCache API
Standardizes in process caching of Java objects in a way that allows an efficient implementation, and removes from the programmer the burden of implementing cache expiration, mutual exclusion, spooling, and cache consistency.

Concurrency Utilities
New kind of BlockingQueue called TransferQueue and a fine-grained parallel computation framework based on divide-and-conquer and work-stealing.

XQuery API
An API for executing XQuery calls and working with results. XQJ is to XQuery what JDBC is to SQL. At a glance, the XQJ API intentionally shares many high-level concepts from JDBC (DataSource, Connection, etc) but supports XQuery specific concepts such as static and dynamic phases, XML-oriented retrieval, etc.

Resource Consumption Management API
Allow for partitioning resources (constraints, reservations) among Java applications and for querying about resource availability (notifications). It will also provide means of exposing various kinds of resources. Example resources are heap memory size, CPU time, open JDBC connections, etc. The goal is to allow resources to be managed so that multiple applications might run simultaneously in a JVM and be given finite amounts of memory, cpu, etc. This JSR will build on top of JSR 121 Isolates.

Swing Application Framework
A simple application framework for Swing applications. It will define infrastructure common to most desktop applications. In so doing, Swing applications will be easier to create.

Beans Binding
An API that allows two properties of two beans to stay in sync. Formalizes an API for connecting JavaBeans.

Beans Validation
Define a meta-data model and API for JavaBeanTM validation based on annotations, with overrides and extended meta-data through the use of XML validation descriptors.

Java Media Components
Support for video to Java. It will initially address playback and ultimately will also cover capture and streaming. Video playback will provide support for both native players and a pure Java player.

JMX 2.0
Updates the JMX and JMX Remote APIs to improve usability of existing features and add new functionality such as annotations for ease of development, federated JMX servers, etc.

Web Services Connector for JMX
A connector for the JMX Remote API that uses Web Services to make JMX instrumentation available remotely. Clients do not have to be Java applications, but can be.

Javadoc Technology Update
New tags and generated Javadoc document representation aimed to increase readability, information richness, and make the Javadoc more approachable to developers learning and using the APIs.

Reified Generics
Currently, generics are implemented using erasure, which means that the generic type information is not available at runtime, which makes some kind of code hard to write. Generics were implemented this way to support backwards compatibility with older non-generic code. Reified generics would make the generic type information available at runtime, which would break legacy non-generic code. However, Neal Gafter has proposed making types reifiable only if specified, so as to not break backward compatibility.

Type Literals
   1. Type<List<String>> x = List<String>.class;   

Annotations on Java Types
enriches the Java annotation system. For example, it permits annotations to appear in more places than Java 6 permits; one example is generic type arguments (List<@NonNull Object>). These enhancements to the annotation system require minor, backward-compatible changes to the Java language and classfile format.

Type Inference
Constructor invocation can be changed from:
   1. Map<String, List<String>> anagrams = new HashMap<String, List<String>>();  
2. to
3. Map<String, List<String>> anagrams = new HashMap<>();

and explicit type references can now be inferred changing:
# timeWaitsFor(Collections.<Man>emptySet());  
# to
# timeWaitsFor(Collections.emptySet());

Closures
A closure is a function that captures the bindings of free variables in its lexical context. Closures support passing functions around and make many anonymous inner class use cases easier to use. In addition, they support additional high-level programming abstractions.

Automatic Resource Block Management
   1. // Start a block using two resources, which will automatically   
2. // be cleaned up when the block exits scope
3. do (BufferedInputStream bis = ...; BufferedOutputStream bos = ...) {
4. ... // Perform action with bis and bos
5. }

Language level XML support
   1. elt.appendChild(  
2. <muppet>
3. <name>Kermit</name>
4. </muppet>);

JavaBean Property Support
   1. public property String foo;   
2. a->Foo = b->Foo;

BigDecimal operator support
Support for manipulating BigDecimal objects with arithmetic operators (just like other numeric primitives) instead of via method calls.

Strings in switch statements
# static boolean booleanFromString(String s) {  
# switch(s) {
# case "true":
# return true;
# case "false":
# return false;
# }
# throw new IllegalArgumentException(s);
# }

Comparisons for Enums
   1. boolean isRoyalty(Rank r) {  
2. return rank >= Rank.JACK && rank != Rank.ACE;
3. }

Chained Invocation
   1. class Factory {  
2. void setSomething(Something something) { ... }
3. void setOther(Other other) { ... }
4. Thing result() { ... }
5. }
6.
7. Thing thing = new Factory()
8. .setSomething(something)
9. .setOther(other)
10. .result();

Extension methods
   1. import static java.util.Collections.sort;  
2. List<String> list = ...;
3. list.sort(); // looks like call to List.sort(), but really call to static Collections.sort().

Improved Catch Clause
# try {  
# return klass.newInstance();
# } catch (InstantiationException | IllegalAccessException e) {
# throw new AssertionError(e);
# }

invokedynamic
Introduces a new bytecode invokedynamic for support of dynamic languages.

Tiered compilation
Tiered compilation uses a mix of the client (JIT) and server hot spot compilers - the client engine improves startup time by using JIT over interpreted and the server hot spot compiler gives better optimization for hot spots over time.

G1 Garbage Collector
G1 (for “garbage first”) is a single collector that divides the entire space into regions and allows a set of regions to be collected, rather than split the space into an arbitrary young and old generation. Sun intends to make this new collector the default in Java 7. (This applies only to the Sun JDK.)

More Script Engine
additional language interpreters to JSE. The JavaScript Rhino engine was added in Java 6. Leading candidates for Java 7 are: JRuby, Jython, and Beanshell.

2008/04/20

GIS For Web Developers

Scott Davis on Seattle NFJS Java Conference


ACT1 - Free Data Available
- Raster Data, Google Satellite
- Vector Data, Google Map
- Hybrid, Google Satellite + Google Map Hybrid mode

Type of Vectors
- Point
- Line
- Polygon

Free Vectors: www.census.gov

Shapefile: well documented proprietary ESRI standard, .shp, .shx, .dbf

 

More data, please: http://www.nationalatlas.gov


For local data, most state and municipal government agencies offer free data as well. 

ACT2 - Projections

Earth is round but maps are flat, projections take fundamentally 3d data and portraying it in 2-dimensions, this procedure introduce error for distance, direction, shape, area. On a Cartesian Planes, X and Y lines form perfect squares, however, on a globe, only the line of Latitude are perfectly parallel, line of Longitude converge at the poles. Different projections attempt to minimize map distortions, common projections are "State Plane" and "UTM".

Reprojection Utility available: GDAL 


ACT3 - Spartial Databases

Why bothers with a database?
- Centralize many scattered files
- Provide security
- Indexing
- Cross dataset queries

PostgreSQL + PostGIS: http://postgis.refractions.net
Visualizing the Data: uDig

ACT4 - Web Services

- Google Maps, undeniably cool, proprietary interface
- Open set of standards available: Open Geospatial Consortium (OGC)
- OGC Features: GetCapabilities, DescribeFeatureType, GetFeature
- Data Service: WFS (Web Feature Service), WMS (Web Mapping Service)
- Open standard, any one can implement them: http://opengeospatial.org/resource/products
- GeoServer: Java based, runs in a Servlet container, provides OGC web services
- MapBuilder: Pure Javascript web client for OGC, included with GeoServer
- OpenLayers: Pure javascript web client, supports OGC, Google Maps, Yahoo Maps, MS Virtual Earth and WorldWind

Acceptance Testing Application Behavior

Venkat Subramaniam on Seattle NFJS Java Conference


How do you ensure your applications meet the expectations of your key customers?

Agile Development, it's all about building relevant working software by constantly getting feedback. Testing is a key ingredient in Agile development. 

Type of tests and Level: 
- UI/Presentation: Watir, Selenium
- Controls/Services: BDD/FIT
- Classes/Models: Unit Testing

Gathering requirement is a challenge. Use case helps, but often tend to be heavy weight and in effective beyond certain point of diminishing returns. Agile development use User Stories. When creating User Stories, 3Cs is important: 
- Card: Feature expressed in an index card
- Conversation: Use short description as starting point for useful discussions that promote exploration and understanding
- Confirmation: Tests are written as a way to confirm completion of feature development

INVEST in User Stories:
- Independent
- Negotiable
- Valuable
- Estimable
- Small
- Testable

FIT: Framework for Integration Testing
- General purpose open-ended framework for expressing tests
- Help focus on business perspectives
- Easy for non-programmers to use (Table represent tests)
- Automated checking and reporting of results
- Useful for Business Rules related to business calculation  and business process/workflow

How does it FIT together?
- Table of Tests, expresses expectations by way of examples
- Fixture, check that the system satisfied the given tests
- Column Fixture, helps test calculations
- Action Fixture, helps test events or actions
- Row Fixture, helps test collections

Tables are in pure html, which includes the test that the fixture will be used to execute on. Fixture is glue code in java that extends from FIT abstract Fixtures.

FitNesse provides a single web based UI for developing, running and viewing results of test. 

BDD - Behavior Driven Design 

- Each behavior is expressed as a test/exercise method
- It tells what the object should do 
- Java Tools for BDD: JBehave, JDave, beanSpec, Instinct
- Groovy Tools for BDD: GSpect, easyb

Reference:

Pragmatic Programmer

http://www.codinghorror.com/blog/files/Pragmatic%20Quick%20Reference.htm


It summarizes the tips and checklists found in book The Pragmatic Programmer. 

10 Ways to use Hibernate Effectively, by Brian Sam Bodden

Brian Sam Bodden on the Seattle NFJS Java Conference. 


- Inheritance, Table per Concrete Class, Table per Class Hierarchy, Table per Subclass
- Identify and use Components in the Mapping
- Dynamic Data Filtering can be enabled in either HBM file or use Annotation
- While generated SQL is good enough in most case, Hibernate does support Customer SQL as well as native SQL with direct JDBC connection. iBATIS alike but you only require to customize the SQL when needed.
- Bulk Operations - Enable JDBC Batching & Be mindful of Session and 2nd Level Cache
- Cache - Session Cache & 2nd Level Cache, Read-Only, Read/Write & Query Cache
- Terracotta - Claims of performance gains in the range of 2-4x when integrating with second level cache
- Hibernate Search - Free text search with Lucene, Annotation driven, luceneQuery = parser.parse("name:beckham or name:galaxy")
- Profiling/Debugging - beware of the Write behind fact of Hibernate. p6spy, Jahia's SQL Profiler, Hibernate Statistics
- Hibernate/Jboss Tools - http://www.hibernate.org/255.html
- Hibernate Tips & Tricks Page: http://www.hibernate.org/118.html

Watch out for Lazy Initialization when you schedule a job

http://www.jroller.com/habuma/entry/a_funny_thing_happened_while


Spring should probably initialize those Job Scheduler more actively. Lazily initialize things like that sounds not a good idea.

Spring Security by Craig Walls

Craig Walls presented the Spring Security Session at the latest NFJS Java Conference in Seattle.

What ACEGI Offers?

- Declarative Security, keeps security details out of your code
- Authentication and Authorization, against virtually any user store
- Support for anonymous sessions, concurrent sessions, remember-me, channel enforcement, and much more
- Spring-based, but can be used for non-Spring web framework

ACEGI's moving parts:

- Security Interceptors, aspects for methods, filters for servlets
- Managers, Authentication, Access Decision, Run-As, After-Invocation
- Authentication Providers
- Access Voters

Security Intercepter - First line of defense
Authentication Manager - Verifies user identity 
Access Decision Manager - Determines if the authenticated user has authority to access the secured resource, by aggregating the result from the Voters
Run-As Manager - Temporarily replaces user's Authentication object for the duration of the current secure invocation
After Invocation Manager - Reviews the object returned from a secured invocation, allows for 'after-the-fact' security

The problem of ACEGI

Every time you use Acegi... A fairy dies... It's a great framework but is very hard to use.

- Lots of moving parts
- Lots of options
- Everything is a <bean> with various options injected with <property>
- Requires lots of XML

Spring Security 2.0

- Released last week (Apr.15th)
- All the Same goodness with some new stuff with much less XML
- Provides a new security configuration namespace for Spring that hides <bean> <property>
- Provides auto-configuration

Method Security

- Intercepting method using Spring AOP
- Or, Annotation Driven

2008/04/19

How CRAP is your java source code?

Crap4j, a Java implementation of the CRAP (Change Risk Analysis and Predictions) software metric - a mildly offensive metric name to help protect you from truly offensive code.


I guess nobody likes it if his code's CRAP level is high. In fact I found this to be really useful when we talk about code quality. 

Download from: http://www.crap4j.org/. Ideally we'd like the build script to output a CRAP report automatically, just like it'll run the test cases automatically.

2008/04/09

Will it Compile?

This small sample project uses two libraries, apache-log4j-1.2.15 from www.apache.org and jpos-1.6.0-r2465 from www.jpos.org. Both are latest version as of the date I write this blog - freshly downloaded. The jpos library comes with no pre-packaged distribution jar file, thus we used ant to build the jar file from it's source files and the build.xml.

Besides that, we have a source file of our own, A.java:

import org.apache.log4j.Logger;

/**
* A.java
*/
public class A {
static Logger logger = Logger.getLogger(A.class);

public static void main(String[] args){
logger.trace("blah blah");
}
}
It does nothing except log a message at trace level. The question here is, will this compile?

The answer? Yes and No. Depends how you compile it.

To demonstrate the problem, we'll just try to use the command line to compile it, instead of using apache-ant or any IDE. It helps us to identify the root of the problem. (Assume lib is where you put your libraries, also we have two version of j2sdk installed, 1.4.2_16 under c:\j2sdk1.4.2_16, 1.5.0_14 under c:\jdk1.5.0_14.)
c:\j2sdk1.4.2_16\bin\javac -classpath lib\apache-log4j-1.2.15\log4j-1.2.15.jar;lib\jpos-1.6.0-r2465\build\jpos.jar src\*.java

Result: Compile success.

c:\jdk1.5.0_14\bin\javac -classpath lib\apache-log4j-1.2.15\log4j-1.2.15.jar;lib\jpos-1.6.0-r2465\build\jpos.jar src\*.java

Result: Compile Success.
Now swap the classpath entries and try it again:
c:\j2sdk1.4.2_16\bin\javac -classpath lib\jpos-1.6.0-r2465\build\jpos.jar;lib\apache-log4j-1.2.15\log4j-1.2.15.jar src\*.java

Result: Compile success.

c:\jdk1.5.0_14\bin\javac -classpath lib\jpos-1.6.0-r2465\build\jpos.jar;lib\apache-log4j-1.2.15\log4j-1.2.15.jar src\*.java

Result:
src\A.java:12: cannot find symbol
symbol : method trace(java.lang.String)
location: class org.apache.log4j.Logger
logger.trace("blah blah");
^
1 error
Surprise, huh? Try it yourself.

Everything comes with a reason. Since jdk1.5, both java and javac recurse the manifest classpath of a jar on the java classpath. Looking into jpos.jar, we found that its manifest file says to use log4j-1.2.8.jar and the trace method wasn't supported till log4j-1.2.12 or above.
jpos.jar manifest file entry:

Class-Path: lib/bsh-2.0b4.jar lib/commons-cli.jar lib/jdbm-1.0.jar lib
/jdom-1.0.jar lib/log4j-1.2.8.jar lib/mx4j-impl.jar lib/mx4j-jmx.jar
lib/mx4j-tools.jar lib/classes

That's the reason why the compilation error happened - javac was instructed to used log4j-1.2.8.jar come with the jpos distribution, instead of the the 1.2.15 that we want it to use.

Conclusion? Well, I don't know what to say here, but this looks something similiar to the windows DLL hell problem. And it was called DLL 'Hell' for a reason.

Further reading: How classes are found?

2008/04/03

Microsoft favours Enterprise Java Platform

Microsoft is using Tomcat and JSP rather than IIS+.Net

Today I happened to catch an error screen from MSN china.
What an ironic screen of Microsoft WEB toolkits marketing policy!



Someone may say it's not true and it was a Fools day joke! O.K, see the further picture that what's the link of http://msn.china.ynet.com:



And more, you can right click any of the url on its page to see the detail of the link properties. What, something like:

http://msn.china.ynet.com/view.jsp?oid=32306246

Although you can say it's just a partner, who cares! Totally wrong, it's Microsoft's Chinese MSN portal which is branded as MSN and Microsoft!

However, it may give Microsoft a chance to say "you see our demos of how unstable of a free software like Tomcat, JSP, Linux, MySql combination! We are considering migrate them to IIS2020+.NET2020+SqlServer2020!".

Wait, one more footnote "until we can make even of MSN in China!".

2008/04/02

TypeSafe Enum and equals()

At first it seems a No Brainer Problem

If you assign the same pre-initialized instance of the same class to two variables, do they always equal to each other? Note that this is the typical pre-jdk1.5 typesafe enum pattern.

public class ReagentType implements Serializable{
private static final String PROTEIN_TYPE = "PROTEIN";
// more types here

public ReagentType PROTEIN = new ReagentType(PROTEIN_TYPE);
// more pre-initialized instance here

private String type;

public String getType(){
return this.type;
}

private ReagentType(String type){
this.type = type;
}

public void checkEquals(ReagentType a, ReagentType b){
System.out.println(a.equals(b));
}

public static void main(String[] args){
ReagentType a = ReagentType.PROTEIN;
ReagentType b = ReagentType.PROTEIN;

checkEquals(a,b);
}

}
Sounds like a no brainer. The answer obviously should be yes. checkEquals() method will print out "true". Always. That is, in an ideal world.

However...

In real world, assuming a & b are both assigned to ReagentType.PROTEIN, in many cases we will see checkEquals() method prints out "false". The standard java equals() compares object identity, which is nothing but the memory location of the object instance, which will most certainly fail in a real world deployment environment.
  1. Consider Distributed Computing. Either a or b has travelled the wire before checkEquals() method gets it, a.equals(b) is false. They resides in two different memory location.
  2. Even in a single server, after serializable/deserialization, it's guranteed that an object will have a different memory location. a equals() the serialize/deserialized copy of itself, is false.
  3. Consider an EJB invoking a method in another EJB, if they're packaged in different deployment JARs and both contains the ReagentType class, depends how the class loading mechanism in app-server works, there might exists many pre-initialized instance of the REAGENT object and they have different memory location.
Solutions.

Oh yeah, there's always solutions. For one, implement the equals() method properly.
public boolean equals(Object obj){
if (obj!=null && obj instanceof ReagentType){
return getType().equals( ((ReagentType)obj).getType());
} else {
return false;
}
}

// hashcode() methods omitted here
For two, for those who're not big fan of the typesafe enum pattern, they can simply fall back to the good old set-of-static-primitive-values enumeration.

A note is that while implementation of the RMI readResolve() method might seem to solve this problem, it actually will fail in scenario 3, since the container may decide not to perform serialize/deserialize if the EJBs resides in the same server. However the readResolve() solution should be safe in non-EJB situation where the class loading situation is simpler.

2008/03/31

Java Constructor Invocation and Instance Variable Initialization

This is a tricky one:


abstract public class BasePayment {
public BasePayment(){
setFakeValue();
}
abstract public void setFakeValue();
}

public final class Payment extends BasePayment{
private String property = null;
public Payment(){
super();
System.out.println("after super(): " + this.getProperty());
}
public String getProperty() {
return property;
}
public void setFakeValue() {
System.out.println("Calling setFakeValue()");
this.property = "property";
System.out.println("After setFakeValue(), property: " + this.getProperty());
}

public static void main(String[] args) throws Exception{
Payment p = new Payment();
System.out.println("'new'ed a Payment, property value: " + p.getProperty());
}
}
What the println in the main() method will output? null? "property"?

It has something to do whether java will initialize the instance variable first, or will invoke the constructor of the super class first. The behaviour is fully documented (it better be!) at http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.8.7.1

And yes, the output is 'null'.

Well well... why another J2EE blog? I benefited from other people's technical blogs, and guess what, it's a good idea to contribute some of my works too. Hope it's helpful and useful, to all of your folks.