Putting It Together

We put the two (Java and JNI code) together by byte compiling the Java wrapper classes and creating two JAR files (gtk.jar and gnome.jar). The C code gets compiled into two libraries libGTKJava.so (containing GDK and GDK code) and libGNOMEJava.so (containing GNOMEspecif stuff).

The two gets linked together through the following code snippet:
	static {
		System.loadLibrary("GTKJava");
	}
for GDK/GTK stuff (gtk.jar) and
	static {
		System.loadLibrary("GNOMEJava");
	}
for the GNOME stuff (gnome.jar).

Important: For the developers convenience the loadLibrary method were called in the JAR files so that it does not need to be done in every program.

The loadLibrary method is called within a static block so that it gets loaded every time before anything else. This will ensure that the native code gets loaded from the library and will enable the JVM (Java Virtual Machine) to execute the code.

Note: The Java Compiler javac does not ensure that the the JNI code for the all the native methods exist while byte compiling the Java code. This means that you will only detect missing JNI calls when running the Java program.

When compiling the JNI code it will not check to see whether all the functions called from within it is there. This means that you will only get error messages when you want to call something in the JNI library. Here is an example of such an error message:
lib/libGTKJava.so.0.4.3: undefined symbol:
gnome_entry_max_saved
      at java.lang.ClassLoader$NativeLibrary.load(Native Method)
      at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1382)
      at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1306)
      at java.lang.Runtime.loadLibrary0(Runtime.java:749)
      at java.lang.System.loadLibrary(System.java:820)
      at gtk.Gtk.<clinit>(Gtk.java:23)
      at TestGTK.main(TestGTK.java:412)