UnsatisfiedLinkError when using a JNI native library from Grails application

前端 未结 2 1425
不思量自难忘°
不思量自难忘° 2021-01-06 03:44

I have an application where I need to use a Native Library: libfoo.so

My code is as follows:

Accessor.java:

pub         


        
相关标签:
2条回答
  • 2021-01-06 03:51

    I noticed that two different class loaders are being used.

    In the non-forked mode, this class loader was being used: java.net.URLClassLoader

    In the forked mode, this class loader was being used: groovy.lang.GroovyClassLoader

    The native library works correctly in the forked mode, so I needed to come up with a hack to load the library with the GroovyClassLoader in the non-forked mode.

    This is how System.load is defined in the JDK Source:

    System.java:

    public final class System {
        ...
        public static void load(String filename) {
            Runtime.getRuntime().load0(getCallerClass(), filename);
        }
        ...
    }
    

    It's calling load0 with the classloader and filename. The obvious solution is to call load0 with your own classloader, but you can't call it since it is package-protected.

    When you write code in groovy, you have access to packge-protected and private methods/variables.

    I can specify my own classloader and load the library, as such:

    class Accessor {        
        static {
            String path = "/usr/lib/libfoo.so"
            //System.load(path);
            Runtime.getRuntime().load0(groovy.lang.GroovyClassLoader.class, path)
        }
        ...
    }
    

    I just tried it, and it's working in non-forked mode.

    0 讨论(0)
  • 2021-01-06 04:07

    My guess is that the Accessor class is being loaded multiple times in different classloaders within the same JVM (assuming grails runs in the same JVM as the embedded Tomcat). Test this by adding debug statements to the static block.

    0 讨论(0)
提交回复
热议问题