2

I'm developing a Grails web application and I need to use a JNI native library to access some specific hardware. For a simple Java application (see below) it works fine. To do this I just have to add the JAR to the Java build path and specify the "Native library location" (I use SpringSource Tool Suite on Windows7).

Working example:

import conceptacid.nativedriver.Driver;
public class Main {
public static void main(String[] args) {
        System.out.println("starting...");
        System.loadLibrary("AudioCardDriver");
        Driver driver = Driver.instance();
        String driverDescription = driver.getDriverDescription();
        System.out.println( "Native application driver: " + driverDescription);
    }
}

However, when I try to add it into my Grails application it fails: Bootstrap.groovy:

import conceptacid.nativedriver.Driver;

class BootStrap {

    def init = { servletContext ->
    System.loadLibrary("AudioCardDriver");
    Driver driver = Driver.instance();
    String driverDescription = driver.getDriverDescription();
    System.out.println( "Native application driver: " + driverDescription);
    }
    def destroy = {
    }
}

the first line System.loadLibrary("AudioCardDriver"); is executed silently without any exception but the next line where I try to use my native code Driver driver = Driver.instance(); fails:

Running script C:\grails\scripts\RunApp.groovy
Environment set to development
  [groovyc] Compiling 1 source file to D:\Projects3\mbr\target\classes
   [delete] Deleting directory C:\Users\VShmyrev\.grails\1.3.7\projects\mbr\tomcat
Running Grails application..
2012-02-24 15:19:49,690 [main] ERROR context.GrailsContextLoader  - Error executing  bootstraps: java.lang.UnsatisfiedLinkError: conceptacid.nativedriver.AudioCardDriverJNI.swig_module_init()V
org.codehaus.groovy.runtime.InvokerInvocationException:   java.lang.UnsatisfiedLinkError:   conceptacid.nativedriver.AudioCardDriverJNI.swig_module_init()V
at grails.util.Environment.evaluateEnvironmentSpecificBlock(Environment.java:251)

...

Caused by: java.lang.UnsatisfiedLinkError: conceptacid.nativedriver.AudioCardDriverJNI.swig_module_init()V
at conceptacid.nativedriver.AudioCardDriverJNI.swig_module_init(Native Method)
at conceptacid.nativedriver.AudioCardDriverJNI.<clinit>(AudioCardDriverJNI.java:70)
at conceptacid.nativedriver.Driver.instance(Driver.java:35)
at conceptacid.nativedriver.Driver$instance.call(Unknown Source)
at BootStrap$_closure1.doCall(BootStrap.groovy:7)
... 26 more
Application context shutting down...

I'm sure I put the DLL into a directory which is in my system PATH but it doesn't help.

What is the right way to use a native library in Grails application both in a development environment and in production?

conceptacid
  • 248
  • 2
  • 13

2 Answers2

2

Your DLL needs to be on a path specified in the Java system property java.library.path. On Windows the PATH environment variable and Linux the LD_LIBRARY_PATH environment variable are added to this system property. You can try logging the java.library.path system property to see if Java is looking in the right place for your DLL.

schmolly159
  • 3,881
  • 17
  • 26
  • The 'java.library.path' property **DOES** contain the path to the folder where the DLL is. – conceptacid Feb 24 '12 at 15:19
  • Actually if the `java.library.path` is wrong then the exception is fired earlier: during the `System.LoadLibrary()` call and the exception is different. It is: ` Error executing bootstraps: java.lang.UnsatisfiedLinkError: no AudioCardDriver in java.library.path`. So the problem is different: the DLL is loaded although the classes couldn't be found. – conceptacid Feb 24 '12 at 15:38
  • How to add anew path to java.library.path? – sop Aug 27 '14 at 10:26
1

I'm guessing that the native library is being loaded multiple times in different classloaders, so forking a new JVM when running the app might help.

Jukka
  • 4,583
  • 18
  • 14
  • I came to the same conclusion: it looks like Groovy runs in a different environment. – conceptacid May 23 '13 at 06:33
  • Look here for a possuible workaround:http://stackoverflow.com/questions/16695000/unsatisfiedlinkerror-when-using-a-jni-native-library-from-grails-application – Jukka May 23 '13 at 06:40