I used Eclipse and built a JNI project on my development machine using the nar-maven
plugin. That compiles on multiple architectures and leaves me with .nar
files.
My problem is that now I want to run the main program in one of the Java classes in the nar
. I keep getting an UnsatisfiedLinkError
when the Java program tries to load the native library that should be in the nar
file. Now I realize that the .so
file needs to be on the java.library.path
but my problem is that I cannot see where to make that point since the only copy is somehow inside the nar
file. I was under the impression that this would be handled behind the scenes because I'm using the auto-generated NarSystem.loadLibrary
method in the Java.
Details follow.
The part of my POM configuring the nar
plugin:
<plugin>
<groupId>com.github.maven-nar</groupId>
<artifactId>nar-maven-plugin</artifactId>
<version>3.5.1</version>
<extensions>true</extensions>
<configuration>
<libraries>
<library>
<type>jni</type>
<narSystemPackage>com.myco.package</narSystemPackage>
</library>
</libraries>
</configuration>
</plugin>
In one of my Java classes, I have a static initializer that calls the auto-generated method for loading the library:
static {
com.myco.package.NarSystem.loadLibrary();
}
After running mvn install
, I have the following files in the appropriate sub-directory of my local .m2/repository
directory:
maven-metadata-local.xml
_maven.repositories
project-0.0.1-arm-Linux-gpp-jni.nar
project-0.0.1.nar
project-0.0.1.pom
project-0.0.1-javadoc.jar
I try to run from the command line with this command:
java -cp /home/myname/.m2/repository/com/myco/project/0.0.1/project-0.0.1.nar com.myco.package.MainClass
That begins to run the appropriate main program, so it found the Java portion. When it gets to the point where it should load the native library - the static block above - it throws the error
Exception in thread "main" java.lang.UnsatisfiedLinkError: no project-0.0.1 in java.library.path
This question, Nar dependency in multi-module maven project, looked like it would be close, but the answer depends on already having the native library "exposed" somehow. I followed the questioner there trying mvn nar:nar-unpack
and mvn exec:java
, but that did not advance me. (Get the same apparently null result from the first as described in that question, and the same exception that I described here for the second.)
Other questions considered:
So how do I run this main program from the command line? If there's some pre-processing step to "extract" the native library what is it? If it's automatic, then what am I missing? Thanks!
I got a tip and finally got it!
This dependency needs to be added to the POM:
<dependency>
<groupId>org.scijava</groupId>
<artifactId>native-lib-loader</artifactId>
<version>2.2.0</version>
</dependency>
After that I could run it using
mvn exec:java -Dexec.mainClass=com.myco.package.MainClass
Trying to run it directly with java
from the command line still crashed, but in this case it crashed because it wasn't finding the jars for the dependencies. Presumably I could run it now without maven if I were to specify class path entries for all of them with the -cp
flag.