This site requires JavaScript, please enable it in your browser!
Greenfoot back

Using Native Libraries with Greenfoot

It's very common that you would want to use a class that loads a native library, and this article documents a method to allow you to do this.

The technique is to 'pre-load' the class that uses the native library. It's 'pre-loaded' in a special way by NativeLoader that makes the native library usable (see end for details).

Downloads

NativeLoader, a class that will load classes that use a native library.

What to do?

First you must download the NativeLoader class (see downloads above) and add it to your Greenfoot project.

Location of .dll, .so and .jnilib

Place native binaries (.dll, .so and .jnilib) files in the root folder of the scenario (don't put them in a sub-folder). This is the only place where Greenfoot can find and load native libraries.

If your library is a .jar

Place your .jar file in the folder '+libs' within the Greenfoot directory. .jars are loaded by Greenfoot if they are within a '+libs' folder, so you can access their classes for compiling your code.

Add the .jar to the NativeLoader class path using the 'addClasspath' method.

If your library is a folder of classes

Place one copy of your library folder in the root of your project. This is so it's classes are found during compilation of your Greenfoot project.

Place a second copy of your library folder within a sub-folder (such as 'mylibs'), in your project. This copy is for use at runtime.

Add the sub-folder to the NativeLibrary classpath using the 'addClasspath' method. This is so the classes are found by the NativeLibrary when you go to pre-load one of them.

Finally load your entry class

The NativeLoader code should be placed within a static block at the top of one of your classes. This ensures that your library classes are pre-loaded using the root class loader before anything else.

Pick the class your using as the entry point for the library you are using, and then load it using the 'loadClass' method on the NativeLoader. Any classes that this class touches within the library are automatically loaded using the same method as your entry class. So typically there is no need to pre-load more then 1 class.

Code Example

The GamePad library uses JInput for talking to gamepads; JInput uses a native library. It's loading code would look like:

    static {
        NativeLoader loader = new NativeLoader();
        
        loader.addClasspath( "./+libs/jinput.jar" );
        loader.loadClass( "net.java.games.input.ControllerEnvironment" );
    }

Why?

Greenfoot uses multiple class loaders in order to allow the same code to be compiled and then reloaded multiple times. However you cannot load a native library multiple times; the JVM does not allow it. So if your code uses a native library it will crash.

This workaround is to have your class loaded using the system or root class loader. Because this is the parent to all class loaders, anything it loads they can see and use. By loading the class once the native libraries are now only loaded once.