Monday, 19 May 2008

Java enum in Java Native Interface (JNI)

A few days ago I started to take interest in JNI (http://en.wikipedia.org/wiki/Java_Native_Interface). JNI is used to call java native methods that are written in other language than Java. Java native methods are usually system dependent and are used to provide functionality that has to be handled by an operating system. Example is creating and handling threads in Java. This functionality is system dependent and has to be handled directly by an operating system (let’s try to open and go through java.lang.Thread class source code in JDK). You can find very useful specification of JNI containing a few examples at http://java.sun.com/j2se/1.5.0/docs/guide/jni/. JNI provides many methods for manipulating Java primitive types, objects, exceptions, non-native methods and so long, but what is missing in the JNI guide is description how to manipulate enums in native code (implemented using e.g. C++) and that’s what I’m going to show you here (using C++).

Let’s assume we have got the following simple enum:

package test;

public enum MyEnum {
VALUE1, VALUE2, VALUE3;
}


Since Java version 1.5 enums are converted to ordinary Java classes so treat them is similar to any other Java object (I recommend you to decompile compiled MyEnum.class file). For the following native method declaration:

package test;

public class SomeClass {
public native String enumTest(MyEnum myEnum);
}


is then, using javah generator (it’s part of JDK, not just JRE), generated following C header:
JNIEXPORT jstring JNICALL Java_test_SomeClass_ enumTest(JNIEnv *, jobject, jobject);
The first parameter is pointer to Java environment, second is Java the object on which is the native method called and the third is the myEnum parameter (notice that the type is object). The way how to handle object in native code is a little bit similar to the Java reflections.

The first thing you have to do is to find the name of the method that returns actual "value" of the enum. You can find in the documentation (http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Enum.html) that every enum has (among others) method name() that returns name of the value of the enum as String (the second usable method is ordinal() ). Now I’m going to show you how to call the name() method in native code implemented using C++:
JNIEXPORT jstring JNICALL Java_test_SomeClass_ enumTest(JNIEnv *env, jobject obj, jobject enumObj) {
jclass enumClass = env->FindClass("test/MyEnum");
jmethodID getNameMethod = env->GetMethodID(enumClass, "name", "()Ljava/lang/String;");
jstring value = (jstring)env->CallObjectMethod(enumObj, getNameMethod);
const char* valueNative = env->GetStringUTFChars(value, 0);
if (strcmp(valueNative, "VALUE1") == 0) {
printf("Enum has the VALUE1 value");
}
// ...
return NULL;
}
On the first line the pointer to the class is obtained using FindClass (http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/functions.html#wp16027) method. You should notice that package name is delimited by "/" and not by ".". On the second line the pointer to the correct method - name() is obtained using GetMethodID (http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/functions.html#wp16660) method. You have to provide correct method’s signature (look into the specification how to get correct method’s signature). The third line calls the method against given object. CallObjectMethod (http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/functions.html#wp4256) means that the method itself returns object (String). The fourth line converts returned string value from UTF-8 (which is used as encoding of strings in Java) to C encoding and finally the last line just compares obtained valued against one of the enum’s values.

Saturday, 26 April 2008

(Synchronized) Singleton design pattern in Java

Singleton falls into the group of simple design patterns. Singleton is a class that has one and only instance in an application. As singletons are usually realized pools (connection, thread, …), cash memories or drivers.

Implementing singleton is quite simple task. The following steps have to be done:
  • declare constructor as private to ensure that no instance of the class can be created
  • implement public static method that returns the only instance of the class
Demonstration of the simple singleton follows:
public final class SimpleSingleton {

private static final SimpleSingleton theInstance = new SimpleSingleton();

private String textAttribute;

private SimpleSingleton() {
textAttribute = "Some text";
}

public static SimpleSingleton getInstance() {
return theInstance;
}

public String getText() {
return textAttribute;
}

}

Because the private constructor, no descendant of the class can be made, so it’s useful practice to declare the singleton class as final to indicate that.

In the example above you can see that instance of the singleton is initialized in the same moment when the class is initialized. If the initialization of the singleton is quite timely-consuming task or it’s not even known whether the singleton would be used then it’s useful to put the initialization off to the first moment when the singleton is needed. Demonstration follows:
public final class LazyInitializationSingleThreaded {

private static LazyInitializationSingleThreaded theInstance;

private LazyInitializationSingleThreaded() {
}

public LazyInitializationSingleThreaded getInstance() {
if (theInstance == null) {
// the dangerous line follows
theInstance = new LazyInitializationSingleThreaded();
}
return theInstance;
}

}

The above example can be safely used only in single threaded application. Because there is no synchronization of the code where the singleton is initialized, it can easily happen that two or more threads would enter the dangerous line. One solution is to synchronize whole method getInstance(), but then the synchronization check would be done whenever the method is called so that the performance would be quite low. The right solution is to synchronize only section where the instance is being initialized. Demonstration follows:
public final class LazyInitializationMultiThreaded {

private volatile static LazyInitializationMultiThreaded theInstance;

private LazyInitializationMultiThreaded() {
}

public static LazyInitializationMultiThreaded getInstance() {
if (theInstance == null) {
synchronized (LazyInitializationMultiThreaded.class) {
if (theInstance == null) {
theInstance = new LazyInitializationMultiThreaded();
}
}
}
return theInstance;
}

}

Keep in mind that singletons should not be serialized, because by de-serialization you get another instance of the singleton.

The last and more complicated case is when the singleton is defined as abstract class with descendants and the singleton while being initialized chooses the right descendant. This is useful when you need to have more singletons of the single type with different behavior. Demonstration follows:
public abstract class SingletonInheritance {

private static class CheerfulSingleton extends SingletonInheritance {};
private static class SadSingleton extends SingletonInheritance {};
private static class DefaultSingleton extends SingletonInheritance {};

private static SingletonInheritance theInstance;

public static SingletonInheritance getInstance() {
if (theInstance == null) {
synchronized (SingletonInheritance.class) {
if (theInstance == null) {
String mood = System.getenv("MOOD");
if (mood == null) {
mood = "";
}
theInstance = chooseInstance(mood);
}
}
}
return theInstance;
}

private static SingletonInheritance chooseInstance(String mood) {
if (mood.equalsIgnoreCase( "CHEERFUL" ))
return new CheerfulSingleton();
else if (mood.equalsIgnoreCase( "SAD" ))
return new SadSingleton();
else
return new DefaultSingleton();
}

private SingletonInheritance() {
}

}

Monday, 24 March 2008

Java 6 compiler API tutorial

One of the new features in Java 6 is compiler API. It let’s you compile any Java source code file on the fly and after compilation you can load compiled class using a class loader and start using it. Because Java compiler doesn’t know anything about classes compiled on the fly, so you can use them only using java reflections.

In the first step we need to prepare a class that is going to be compiled using Compiler API. I prepared the following simple class:

package com.blogspot.mike_java;

public class ToBeCompiled {

public void callMe() {
System.out.println("Method callMe has been called");
}

}

And saved it to the directory “d:\javafiles\src” (absolute path to the ToBeCompiled.java file is “d:\javafiles\src\com\blogspot\mike_java\ ToBeCompiled.java”) and prepared directory for compiled files “d:\javafiles\bin”. The next step is to prepare a class that compiles ToBeCompiled class, loads it and runs method callMe() on an instance of it. I prepared in my favorite IDE Eclipse following class:

package com.blogspot.mike_java;

public class CompilerAPITest {

public static void main(String[] args) {
// source code is going to be here
}
}


All following source code lines will be in the main method of the CompilerAPITest class.

At first we need to get instance of JavaCompiler and StandardJavaFileManager:

JavaCompiler jc = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager sjfm = jc.getStandardFileManager(null, null, null);


The next step is to get Iterable collection of files to be compiled and prepare options for compiler (you can find list of compiler options at http://java.sun.com/javase/6/docs/technotes/tools/windows/javac.html):

File javaFile = new File("d:/javafiles/src/com/blogspot/mike_java/ToBeCompiled.java");
Iterable fileObjects = sjfm.getJavaFileObjects(javaFile);
String[] options = new String[]{"-d", "d:/javafiles/bin"};


The next step is to compile Iterable collection of java files and close file manager:

jc.getTask(null, null, null, Arrays.asList(options), null, fileObjects).call();
sjfm.close();
System.out.println("Class has been successfully compiled");


After this step all compiled classes would be saved in directory “d:\javafiles\bin”. The next step is to load compiled class using class loader and run method callMe. At first we need to load compiled class:

URL[] urls = new URL[]{ new URL("file://d:/javafiles/bin/") };
URLClassLoader ucl = new URLClassLoader(urls);
Class clazz = ucl.loadClass("com.blogspot.mike_java.ToBeCompiled");
System.out.println("Class has been successfully loaded");


And get the method callMe using reflections:

Method method = clazz.getDeclaredMethod("callMe", null);


Finally we need to create new instance of the just loaded class and call method callMe on it:

Object object = clazz.newInstance();
method.invoke(object, null);


You can download source codes at http://rapidshare.com/files/102030988/compiler_api.zip. I hope that this tutorial was useful for you.