Wednesday, September 30, 2009

Ant Task to generate GWT Classes and servlets

Yet Another Ant Task.
I made a task which given:
A source dir, a source classpath, and destination dir,
A series of source interfaces and a new GWT name,

My task will generate all the GWT plumbing. Namely the Service interface, the ServiceAsync interface, and a Servlet Implementation. If you specify a delegate, the the servlet will implement the interface by calling the methods in the delegate.
Pretty sweet.

I learned a lot about how "Generic" info about classes can be obtained through the reflection API. You might think that all the type parameter stuff is erased, a-la
Section 4.6 of the Java spec., but it is all there in the class, available through reflection. On the other hand, this leads to a paradox, because the it's not supposed to be there.


For example, let's say you have:

public interface Foo{
List<String> someMethod();
}

The compiler halts with an error if you try to implement Foo with this class:

public class Bar implements Foo{
List<String> someMethod(){return new ArrayList<String>();}
}

Because the type parameter of the returned List<String> has been "erased", and the return type in the interface is actually just List.

But if you were using reflection to generate class source you would still find the <String> type parameter. So to get your implementation to compile, you must discard the Type info.

At least that's the way it seems to work :)

Thursday, September 24, 2009

How to make JNI apps reloadable

JNI has this annoying "feature" , that makes is very difficult to run an application ( or ant task, or whatever) that loads a native library.
When you load a class ( lets call it Foo ) that loads loads a DLL, loadLibrary is called on the ClassLoader that loaded Foo.
If you try to load the Foo class again, and the library is still loaded, then loadLibrary will fail with a java.lang.UnsatisfiedLinkError.

The DLL that Foo loaded will NOT be unloaded when Foo is garbage collected. The DLL will not be unloaded until the ClassLoader, and all the other classes that were loaded with Foo's ClassLoader are garbage collected. If that ClassLoader is the System ClassLoader, it will never be unloaded while the JVM is running.

This makes it an exceptional pain to try and re-deploy an app to an application server.
There is a lot of whining about this, and a lot of bad advice. So here is a WORKING solution.

A) All the classes that load native libraries (JNI clients) should implement interfaces for their use.
B) All the other classes should ONLY reference the interfaces, never the classes themselves.
C) JNI client classes must be loaded by a separate classloader then the other classes.
D) The instances of the JNI client classes must be instantiated by reflection, not by directly calling a class’s constructor. This prevents the class being loaded by a non-JNI ClassLoader

To accomplish this, I created a VolitileFactory class, that subclasses URLClassLoader. It has a makeInstance method, which loads the JNI client classes, and invokes the correct constructor via reflection. The VolitileFactory instance is a field of the Anchor class. Anchor has static methods to obtain implementers of the JNI client’s interfaces. Anchor holds the only reference to the factory. When the app shuts down, that reference is deleted, System.gc() is called, and the libraries unload.

Saturday, September 12, 2009

Summer break is over, back to the Toy.

I re-implemented the event loop and the event objects to be in Java instead of native code.

There is a Java EventMachine. A client uses getTheEventMachine to get only instance. It maintains a timer and a FIFO blocking queue of SimpleEvents. SimpleEvents are added to the queue by the addEvent method of EventMachine. At the preset interval, the queue is locked, and the SimpleEvents in it are dispatched to processEvent in the UpperDeck one at a time, until they are all processed, or until a set amount of time has passed. Then, dispatching ceases and the queue is unlocked. processEvent in UpperDeck processes the event, and in a finally clause, calls the delete method of the event.

This system is used by native code via a C++ JEventMachineConnector class. This maintains a global reference to a thread in the EventMachine where addEvent executes. So when addEvent is called on JEventMachineConnector, it joins the Java thread, calls addEvent on EventMachine, and upon completion, detaches from the thread.

The SimpleEvent interface is an immutable collection of three properties: source, type and message, and a delete method. However the implementation of SimpleEvent is not simple. An implementation consists of a Java object SimpleEventJavaImpl, and it’s native shadow. The Java object implements SimpleEvent, exports a delete method, and maintains a pointer to the native shadow object. This delete method is actually implemented natively. Upon garbage collection, if the native resources have not been freed, SimpleEventJavaImpl calls its own delete method. The native shadow object maintains a link to the Java object, and native versions of the initial value of the properties of the SimpleEvent. It also implements logic to create SimpleEventJavaImpl objects from the native side. The hairiness of SimpleEvent implementation comes from the logic to instantiate one from the native or Java side, and then to delete all native resources.

The Toy also grew much hair implementing Java<->Native exception handling, and other error management. I learned far more then I wanted to know about C++ templates, Unicode on Windows, and why the C++ preprocessor is pure freaking EVIL.