Java JNI integration: System.load fails

6 vues (au cours des 30 derniers jours)
Sven Mertin
Sven Mertin le 5 Juin 2020
Commenté : Sven Mertin le 9 Juin 2020
Hey there!
I am currently trying to get Java code running in Matlab using a native library. My problem is not the general setup, but a single specific dll file that constantly causes UnsatisfiedLinkError exceptions. I am not able to load this specific dll file from within Java (I am trying to connect a software called SUMO to Matlab). So to give you more details, see this example code in java:
import org.eclipse.sumo.libsumo.*;
public class LibsumoTest {
public static void main (String[] args){
System.out.println("Let's go!");
try{
System.out.println("Loading dll: " + args[0] + "\\libsumojni.dll");
System.load(args[0] + "\\libsumojni.dll");
System.out.println("Success!");
// Do stuff with native library
System.out.println("Version: " + libsumo.getCMD_GETVERSION());
}
catch(UnsatisfiedLinkError ex){
System.out.println(ex.getLocalizedMessage());
System.out.println(ex.getMessage());
ex.printStackTrace();
}
}
}
Running this on (windows) command line interface using the provided jar file:
cd C:\test
javac -cp "libsumojni.jar;C:\test" LibsumoTest.java
java -cp "libsumojni.jar;C:\test" LibsumoTest "C:\test"
the output is:
Let's go!
Loading dll: C:\test\libsumojni.dll
Success!
Version: 0
As you can see, the native library is working in this context (of course I tested way more complicated examples, this is just a minimal example).
Now I want to do the same in Matlab, but if I run this code in matlab:
cd C:\test
javaaddpath(pwd);
javaaddpath([pwd '\libsumojni.jar']);
LibsumoTest.main(pwd);
I always get this error:
Let's go!
Loading dll: C:\test\libsumojni.dll
C:\test\libsumojni.dll: Die angegebene Prozedur wurde nicht gefunden
C:\test\libsumojni.dll: Die angegebene Prozedur wurde nicht gefunden
java.lang.UnsatisfiedLinkError: C:\test\libsumojni.dll: Die angegebene Prozedur wurde nicht gefunden
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1941)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1824)
at java.lang.Runtime.load0(Runtime.java:809)
at java.lang.System.load(System.java:1086)
at LibsumoTest.main(LibsumoTest.java:12)
I am using Matlab 2019b (64 bit), my jdk is 64 bit, the dll file is 64 bit. I also tried to use the static classpath instead of the dynamic one with no change. As long as I take another dll file, there is no error while loading. I made so many tests with different dll files which all worked that I come to the conclusion that there must be something special with this dll that prevents Matlab from loading it. Here is a screenshot of dependency walker with the loaded dll:
Even the function names are correct regarding the jni naming convention. However, there seem to be some problems (red font) but I am not really familiar with them. Do you have an idea where the problem can come from and why in the case using java without matlab this is working? I am also confused by MSVCP140.dll and VCRUNTIME140.dll which are displayed as 32 bit instead of 64 bit?
Any ideas?
Thank you very much
Sven
  2 commentaires
Sven Mertin
Sven Mertin le 8 Juin 2020
So I think I found the problem and it's even more challenging:
The libsumojni.dll depends on xerces, to be more specific it is linked to a xerces-c_3_2.dll which is also provided by the software I try to include into matlab.
Xerces is also used by Matlab, within <matlabroot>/R2019b/bin/win64 there is a file named xerces-c_3_2.dll, too.
But these two dll files are different! Their function names are the same, but the function adresses as well the file sizes differ. My guess is that if I am loading the dll from java within Matlab, the dll included in matlab is shadowing the dll given in the library path. Therefore I copied the matlab version of this file to my build folder for verification. Now I am getting the exact same error without using matlab at all (worked before). This error is now perfectly reproducible.
My conclusion now is that the two different versions of xerces-c_3_2.dll and the shadowing of the file within matlab are the reasons for my errors. Unfortunately, matlab won't run with the other xerces-c_3_2.dll and vice versa.
At the moment I don't have a clue how to continue.
Is there a way to load a native library through Java within matlab which depends on dlls that are shadowed by matlab files? I want to ignore them in this case.
Thanks!
Sven
Sven Mertin
Sven Mertin le 9 Juin 2020
I have resolved my problem:
  1. I renamed my version of the dll file from 'xerces-c_3_2.dll' to 'xerces-c_3_s.dll'
  2. I modified my compiled persona dll in a hex editor and changed the dependency acc. to the naming in (1)
  3. 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.

Connectez-vous pour commenter.

Réponses (0)

Catégories

En savoir plus sur Java Package Integration dans Help Center et File Exchange

Produits


Version

R2019b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by