jna Native.LoadLibrary无法在服务器上加载库(在本地工作)

时间:2018-03-19 09:32:04

标签: java tomcat noclassdeffounderror jna

我使用JNA在java项目中加载c ++库(.so)。我将我的库打包在jar中,并在实例化使用它的java类时从jar加载它。我这样做就是这样:

  • mvn install编译c ++代码并将结果动态库打包在jar中。
  • 我在实例化LibraryWrapperClass时调用静态上下文

    System.load( temp.getAbsolutePath() );
    

其中temp是一个临时文件,包含在jar中找到的库。此代码基于此处的工作adamheinrich - 我调用Native.loadLibrary(LIBRARYPATH)将库包装到java类中。

    private interface Wrapper extends Library {
        Wrapper INSTANCE = Native.loadLibrary( C_LIBRARY_PATH, Wrapper.class );

        Pointer Constructor();
        ...
    }
  • 我运行测试并验证库已找到并启动并运行。
  • 我使用依赖于这个项目的java web项目。它使用tomcat并在本地运行良好。

我的问题是,当我在服务器上部署时,LibraryWrapperClass无法实例化。服务器上的错误是:

java.lang.NoClassDefFoundError: Could not initialize class pacakgeName.LibraryWrapperClass
    at java.base/java.lang.Class.forName0(Native Method)
    at java.base/java.lang.Class.forName(Class.java:375)
    at org.hibernate.annotations.common.util.StandardClassLoaderDelegateImpl.classForName(StandardClassLoaderDelegateImpl.java:57)
    at org.hibernate.boot.internal.MetadataBuilderImpl$MetadataBuildingOptionsImpl$4.classForName(MetadataBuilderImpl.java:758)
    at org.hibernate.annotations.common.reflection.java.JavaReflectionManager.classForName(JavaReflectionManager.java:144)
    at... 

此错误似乎找到了库,因为没有抛出UnsatisfiedLinkError异常。但其他事情却失败了。有人知道会发生什么吗?我怎么调试?

我记得一切都在当地完美运作。

1 个答案:

答案 0 :(得分:1)

  

我该怎么调试?

<强> 1。与strace

strace将为您提供Tomcat尝试打开的文件:strace -f -e trace=file -o log.txt bin/startup.sh

在此之后,在log.txt或其他找不到的文件中查找packageName:

egrep ' open.*No such file' log.txt

<强> 2。使用JConsole

启用JMX,启动JConsole,转到VM摘要选项卡,并仔细检查/比较VM参数/类路径/库路径/启动类路径

第3。依赖列表与ldd

如果依赖性问题可能是问题,ldd sharedLibraryFile.so命令会列出所有依赖项,并允许跟踪哪些可能缺失。