0

I use JNA to load a c++ library (.so) in a java project. I package my library inside the jar, and load it from the jar when instantiating the java class that uses it. I do all this like so:

  • mvn install compiles the c++ code and packages the outcome dynamic library inside the jar.
  • I call in a static context when instantiating the LibraryWrapperClass the following

    System.load( temp.getAbsolutePath() );
    

where temp is a temporary file containing the library which was found in the jar. This code is based on the work found here adamheinrich - I call Native.loadLibrary(LIBRARYPATH) to wrap the library into a java class.

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

        Pointer Constructor();
        ...
    }
  • I run tests and validate that the library was found and up and running.
  • I use a java web project that depends on this project. It uses tomcat and runs fine in local.

My issue is that when I deploy on the server, the LibraryWrapperClass cannot instantiate. Error on server is:

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... 

This error seems that the library is found, since there is not the UnsatisfiedLinkError exception thrown. But something else is failing. Do someone know what could happen? How could I debug?

I recall that everything works perfectly in local.

Yvus
  • 338
  • 1
  • 20
  • I assume `pacakgeName` is just a type, right? – Thomas Mar 19 '18 at 09:34
  • I did not want to disclose the exact package name since it contains private information. – Yvus Mar 19 '18 at 09:38
  • It doesn't behave differently, of course. The only things that are different are the effective paths. – user207421 Mar 19 '18 at 10:02
  • So you mean that the library is not found? How can I suggest to have it look at the right location? And how can I prove your point is the one causing my troubles? – Yvus Mar 19 '18 at 10:14

1 Answers1

1

How could I debug?

1. with strace

strace will give you what files Tomcat is trying to open : strace -f -e trace=file -o log.txt bin/startup.sh

After this, look for packageName in log.txt, or other files not found with :

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

2. with JConsole

Enable JMX, launch a JConsole, go to VM summary tab, and check/compare very carefully VM arguments/classpath/library path/boot class path

3. dependency listing with ldd

If a dependency issue is likely to be the problem, the ldd sharedLibraryFile.so command lists all the dependencies and allows to track which one might be missing.

Yvus
  • 338
  • 1
  • 20
Eugène Adell
  • 3,089
  • 2
  • 18
  • 34
  • Thanks for your answer. It is strange because the package name is not appearing in the log. I don't even feel this log contains any error, although I am not sure on how to interpret the log. And the c++ libc.so.6 is found together with g++. – Yvus Mar 20 '18 at 10:02
  • I believe that the library is found but that a dependency is missing. I do not know how to spot it... – Yvus Mar 20 '18 at 10:13
  • 1
    @EJP said you have different paths, this would lead to file not founds that strace is able to exactly see. I would do egrep ' open.*No such file' log.txt to find out what files were not found – Eugène Adell Mar 20 '18 at 10:37
  • If I do `grep ' open.*' log.txt` then I see that all the files that are not found first finish to be found in an alternative directory. And none refer to a path I provided. Thanks – Yvus Mar 20 '18 at 13:04
  • We'll get a headache with your story. Something must be different between your environments or it would work. You are running Tomcat, right ? Enable JMX, launch a JConsole, go to VM summary tab, and check/compare very carefully VM arguments/classpath/library path/boot class path – Eugène Adell Mar 20 '18 at 13:37
  • I will edit my answer now, to add reference to JConsole, ok ? – Eugène Adell Mar 20 '18 at 13:39
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/167186/discussion-between-eugene-adell-and-yvus). – Eugène Adell Mar 20 '18 at 13:58
  • 1
    Option 3 was the solution to my problem. Thanks – Yvus Mar 21 '18 at 14:25
  • You're wellcome @Yvus. This was a challenging and exciting troubleshooting ;) – Eugène Adell Mar 21 '18 at 14:26
  • btw @Yvus I left a comment in the discussion. – Eugène Adell Mar 23 '18 at 08:28