Reputation: 551
I have a 3rd party native library (let's call it test.dylib) which I am trying to load through JNA in a Maven project. output of otool -L test.dylib is
/Library/Frameworks/test/Versions/A/test (compatibility version 1.0.0, current version 1.0.0)
/System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa (compatibility version 1.0.0, current version 19.0.0)
/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 945.11.0)
/usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 65.1.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 169.3.0)
/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 744.1.0)
If I paste the test.dylib file at location "/Library/Frameworks/test/Versions/A/test " from otool -L output. And load the file through JNA, it works fine. But if I keep the test.dylib under resource folder, I get error.
java.io.IOException: Native library (darwin-x86-64/test.dylib) not found in resource path (/Users/username/Downloads/TestJNA/target/classes:
Even though I can see the dylib file present in /target/classes folder. Can someone suggest, how can I achieve calling dylib from resource folder? I don't want to paste the dylib file at this location "/Library/Frameworks/test/Versions/A/test".
This is how I am loading native library.
public class TestJNA {
public interface Perception extends Library {
Perception Instance = (Perception) Native.load("test", Perception.class);
void method1();
int method2(int a, int b, int c);
}
public static void main(String[] args) {
Perception.Instance.method1();
System.out.println(Perception.Instance.method2(1,2,3));
}
}
Upvotes: 1
Views: 1268
Reputation: 9121
While the error message you received only lists one search path, JNA actually checks multiple locations for your library. As documented in the NativeLibrary class javadocs:
A search for a given library will scan the following locations:
jna.library.path
User-customizable pathjna.platform.library.path
Platform-specific paths- On OSX,
~/Library/Frameworks
,/Library/Frameworks
, and/System/Library/Frameworks
will be searched for a framework with a name corresponding to that requested. Absolute paths to frameworks are also accepted, either ending at the framework name (sans ".framework") or the full path to the framework shared library (e.g. CoreServices.framework/CoreServices).- Context class loader classpath. Deployed native libraries may be installed on the classpath under
${os-prefix}/LIBRARY_FILENAME
, where${os-prefix}
is the OS/Arch prefix returned byPlatform.getNativeLibraryResourcePrefix()
. If bundled in a jar file, the resource will be extracted tojna.tmpdir
for loading, and later removed (but only ifjna.nounpack
is false or not set).You may set the system property
jna.debug_load=true
to make JNA print the steps of its library search to the console.
Note the os-prefix
directory in item 4 above. You have included your library directly on the classpath (from the comments, /Users/username/Downloads/TestJNA/src/main/java/test.dylib
). However, as the error message states, it needs to be in the darwin-x86-64/
directory on your classpath, e.g., /Users/username/Downloads/TestJNA/src/main/java/darwin-x86-64/test.dylib
;
You may wish to use src/main/resources
in preference to the java
subdirectory for non-java code.
Your attempt to set the system library path to your raw source code directory doesn't work for the compiled code where it is looking in the target/classes
directory structure.
Note that you can get further debugging information by setting the system property jna.debug_load=true
.
Upvotes: 2