UnsatisfiedLinkError when using a JNI native library from Grails application

两盒软妹~` 提交于 2019-11-30 22:58:38

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.

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!