#1926 Native Dependencies

geo Thu 21 Jun 2012

Questions about native dependencies:

What is the easiest way to include native dependencies such as DLLs in a Fantom application / project so that they will be available at runtime.

For example, you have a 3rd party Jar, and put it in the <fantom>\lib\java\ext directory, where can you put DLLs that the Jar depends on, is <fantom>\lib\java\ext\win32-x86 added to the PATH?

Or is the only way to set the PATH before executing your Fantom code? Is there a way of modifying the PATH used by Fantom at runtime?

Or do you need to load those DLLs via Java (or .Net) using System.load() / System.loadLibrary()?

Thanks.

brian Fri 22 Jun 2012

There is nothing special in Fantom runtime, you'll have to do whatever is required by the JVM which is typically sticking the DLL into your path and calling System.load. There is a way on some systems to put the DLL into your JAR (this is how SWT works), but I don't know the details.

geo Fri 22 Jun 2012

SWT includes the dlls, and at runtime unpacks them into <user.home>/.swt I believe.

I guess if you wanted a self contained Jar containing dlls, you could include some unpacking code and load the libraries from there. But if you don't have access to the code that loads the libraries you would need to make sure they could be found on the PATH, one way to do that would be modify the java.library.path using reflection (which is a bit hacky).

go4 Sat 23 Jun 2012

Another way is to use JVM -D options. for example:

./etc/sys/config.props:

java.options=-Xmx512M -Djava.library.path=/home/jed/code/fan3d/lib/lwjgl-2.8.3/native/linux/

geo Tue 26 Jun 2012

Is there a way of setting the java.options at runtime?

brian Tue 26 Jun 2012

Is there a way of setting the java.options at runtime?

Not really, those are passed to JVM at startup.

In some cases depending on what you want, you can change System.getProperties() at runtime or maybe tweak things with javax.management APIs.

But if you are trying to change the DLL load path at runtime, I think I tried to go down that path and never figured it out.

geo Wed 27 Jun 2012

The only way I know that works is

public static void addLibDir(final String dirToAdd) throws IOException {

if (dirToAdd == null) {
	throw new NullPointerException("dirToAdd is null");
}

try {
	final Field field = ClassLoader.class.getDeclaredField("usr_paths");
	field.setAccessible(true);

	final String[] paths = (String[]) field.get(null);
	for (int i = 0; i < paths.length; i++) {
		if (dirToAdd.equals(paths[i])) {
			return;
		}
	}
	final String[] pathsIncDirToAdd = new String[paths.length + 1];
	System.arraycopy(paths, 0, pathsIncDirToAdd, 0, paths.length);
	pathsIncDirToAdd[paths.length] = dirToAdd;
	field.set(null, pathsIncDirToAdd);

	System.setProperty("java.library.path",
			System.getProperty("java.library.path")
					+ File.pathSeparator + dirToAdd);

} catch (final IllegalAccessException e) {
	// TODO handle as required or throw
	e.printStackTrace();
} catch (final NoSuchFieldException e) {
	// TODO handle as required or throw
	e.printStackTrace();
}

}

But that's using reflection, so may break if JRE/JDK implementation changes.

Login or Signup to reply.