Loading multiple dependent libraries via JNI and DllMain - java

I have a JNI library that depends on a third party library.
I can load and use the library by first doing a System.Load on the third party library then doing System.Load on my library. This works.
I recently introduced a DllMain (does not do anything) in my library and now when the library is loaded I get java.lang.UnsatisfiedLinkError: fullpath\name.dll: Can't find dependent libraries
If I attach a native debugger to the process and set a breakpoint in the DllMain function the breakpoint is entered and the Library is loaded correctly (no UnsatisfiedLinkError )
Does anyone have any idea or pointers as to what might be going on?

I suppose that in you didn't link dlls that your dll are using to you java runtime. It must be in your working directory or use -Djava.library.path=fullpath.

Related

Java JNI, multiple versions of a dll: How to specify which dll is being used for native calls (matlab jvm)

I am facing a special situation. I am trying to run a java application within matlab. My application uses an external dll which depends on another dll (xerces-c_3_2.dll). My problem is that matlab also contains a xerces-c_3_2.dll in its root folder.
Unfortunately, these two dll files are different! It is not possible to change the library path of the jvm within matlab in a way, that the 'matlab'-version of the dll is not shadowing my dll version (it's automatically loaded on matlab startup). Due to this, my application is always throwing exceptions that a procedure could not be found because its using the wrong version.
Since matlab won't start with my version of the dll, my idea is now to rename the dll to 'xerces-c_3_2_myVersion.dll' and load it redundantly.
How can I tell the jvm for a specific jni call which native interface should be used?
In my jni interface the known
public final static native lines are defined, but I never faced the question how to specify the dll in case of redundant native functions?
Any ideas? Thank you!
Sven
I have resolved my problem:
I renamed my version of the dll file from 'xerces-c_3_2.dll' to 'xerces-c_3_s.dll'
I modified my compiled personal dll in a hex editor and changed the dependency acc. to the naming in (1)
I loaded the modified dll with the changed dependency using java within matlab. Now it's working without any problems!
So technically it was more a windows library thing rather than a java question.

Linking Java with C++ statically using JNI

Is it possible to link a C++ library to a Java program statically, in a way that will make them into a single file ,just like linking 2 C++ libraries?
(I read that java programs can also be compiled to EXE).
Theoretically this should be possible to create one EXE that already includes the required JNI functions used by the JVM.
This EXE would have to load the Java part by starting a JVM instance in the same process (by loading jvm.dll and executing it as shown in question JNI Java in c++).
The Java-EXE-wrapper I know do not support something like this as they come with a pre-compiled EXE that gets the used JAR attached as resource. Therefore I assume you would have to build you own C/C++ executable and implement all the functionality you need.
When I use JNI I include the dll with JNI support into my jar file. Then access it by classpath. You will have single jar file.
It isn't possible unless you have access to a static version of the jvm.lib library. It is distributed as a dynamic-link library referring to jvm.dll. You can't do this.

Calling dlopen from a shared library loaded via JNI makes previously loaded symbols invisible

I have a Java application which interacts with native code using JNI. The native code compiles a file at runtime and attempts to load this file using a dlopen call. This call fails and I get a warning stating
Could not load library (x):(x) undefined symbol: y
However when I have a native application starting a JVM via JNI run the same code, this error does not occur and it runs as expected. I am suspecting Java is doing something fancy which causes the already loaded libraries to be invisible for the library that is loaded with dlopen.
This I did to diagnose the problem:
Confirmed in which shared library the symbol that was supposedly undefined is located using objdump
Confirmed this library is loaded by using gdb (via eclipse - the library was listed in the modules pane)
Printed LD_LIBRARY_PATH just before the dlopen and confirmed Java passes it through (It did add Java's lib dirs but the original dirs were still there)
I have been trying to solve this for a while now, but I can't figure out what is going on. Especially because it does work when the JVM is loaded from a native application.
Thank you in advance!
I finally found the answer. The solution was to recompile the shared library that contained the symbol that was not found with the -Wl,--export-dynamic linker flag.
Interestingly I did not program that shared library myself and I would expect the default compilation to add the flag since it was needed for software using it to function properly.
Either way it is a open source project so I could compile it with the proper flags set.

Loading 2 .so native libs in linux from Java via JNI

I'm having some problems loading 2 libs where one depends on another in Linux. Let's say I have 2 libs, libA.so and libB.so, libB.so depends on libA.so (calling functions from it).
I need to load libB.so from Java via JNI and call some native methods from it.
SO what I'm trying to do is:
static {
System.loadLibrary(A);
System.loadLibrary(B);
}
(Both libraries reside in java.library.path).
Under Win32, it works fine - B.dll sees that A.dll is already loaded, and doesn't try to load it itself (using PATH lookup).
While on Linux, it doesn't work. Additional logging shows, that System.loadLibrary(A); executes correctly, and libA.so is getting loaded fine, then, when we I try to load B, it looks for library libA.so in the LD_LIBRARY_PATH, and it fails (both libs are in java.library.path, but NOT in LD_LIBRARY_PATH).
Does someone why does it happen? Is it related to the way Linux runtime linking works?
I see a lot of way to work it around, but first want to understand the bottom line of that.
Thanks,
Mikhail

Create a Java library (jar) from C code

Greetings,
I am trying to use this api:
http://code.google.com/p/vavi-sensor/
for using the macbook accelerometer in Java code.
I am put the .c files into my library but I am still getting a
java.lang.UnsatisfiedLinkError: no SmsWrapper in java.library.path
I assume this is because it's still in .c files while all my other libraries are .jar. How can I go about getting this into a jar or other loadable format (jnilib, etc)?
thanks
You need to read about JNI or JNA. JNA is easier, but you still need to compile the C as a library, then follow the JNA documentation.
The .c files are just source code. You need them compiled for the appropriate machine, packaged into a shared object library, and then referenced by native methods in a wrapper Java class.
The JNI tutorial has all the information you'll need, although it doesn't go into detail about the non-Java side of things as most people doing this already know about programming in C and building shared object libraries.

Categories

Resources