SWIG c++ Java DLL Windows - java

my problem: creating a java wrapper for a c++ DLL.
I know, there are many articles about this issue but so far no solution for me.
Then problem:
I have java 1.6 up 29 32-bit installed on my windows 7, 64 bit, at C:\java\jdk.
This path is part of path variable (open cmdline anywhere, i can always calls javac...)
I have latest swig, which successfully created python and perl wrappers for my DLL.
When i buld java/class sample with VS2008 - which completes without errors - and try to run the runme.java i get the error:
UnsatisfiedLinkError
-> Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help
the DLL is very simple. Statically linked to runtime libs (/MT). No dependecies but still
getting this error.
Please note: the swig sample does not work. Java installed. Also the tcl sample does not work.
tcl 8.4 installed (similar error).
Any help is appreciated.
Thank you

Your class has been compiled successfully, and the native library has been compiled successfully. The issue is that the Java code needs to load, at runtime, the shared object which you generated with Visual Studio.
Try passing -Djava.library.path=<directory containing your DLL> when you run the class.

From the looks of what you've described it seems like you've not loaded the DLL you compiled within Java before trying to call one of the (generated by SWIG) JNI methods.
I normally use something like:
%pragma(java) jniclasscode=%{
static {
try {
System.loadLibrary("module");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load. \n" + e);
System.exit(1);
}
}
%}
in my SWIG interface file to cause the DLL to be loaded automatically at runtime by the Java code.
(You'll need to make sure the DLL is placed somewhere appropriate with respect to library paths on your system).

Related

How do I build my java classes to not result in NoClassDefFoundException from JPype?

I have a Netbeans project of some Java code I wrote many years ago. I am doing a new project in python now, but I have a Java class in my old project that has some handy MIDI code that I would like to use since I have so far been unable to easily translate to python.
I used pip to install JPype, used Netbeans to build the class I need, and moved the .class file into the same directory as my python file. Here is an abridged part of my python code to call the Java class, which is called "SoundTester" and was in a package called "soundsynthesis".
from jpype import startJVM, shutdownJVM, java, addClassPath, JClass, JInt
import jpype.imports
startJVM(convertStrings=False)
try:
pass # Not sure why we need a pass here
tester = JClass('soundsynthesis/SoundTester')
except Exception as e:
print(f"Exception: {e}")
shutdownJVM()
The result is
Exception: java.lang.NoClassDefFoundError: soundsynthesis/SoundTester
Note that if I change soundsynthesis/SoundTester to just SoundTester, I get this slightly different exception:
Exception: java.lang.NoClassDefFoundError: SoundTester (wrong name: soundsynthesis/SoundTester)
I'm thinking that the issue may be due to me moving the .class files out of the Netbeans project and into my working directory, but I don't know how to resolve that. I also tried moving the java files into my desired directory and just using javac to build them.
I have ensured that my version of python and the jdk are both 64-bit, as that was a similar question's issue.
This is an issue with the path specification. It is true that JNI usually refers to classes using the slash notation. However, in this case JClass calls the Java Class.forName() method which requires dot notation rather than JNI. Thus the solution to this issue is to use JClass('soundsynthesis.SoundTester').
Here is an example using the test harness in jpype.
import jpype
jpype.startJVM(classpath=['test/classes'], convertStrings=False)
j = jpype.JClass('jpype.common.Fixture') # success
j = jpype.JClass('jpype/common/Fixture') # fails
In general, JPype uses the notations that are found in Java itself rather than those imposed by JNI. For further examples, please see the section "Import a class without tld" in the quick guide.
I solved the issue. Perhaps not the most elegant solution, but I modified the Java classes so they instead were not in any package (or rather they were in the default package) and then moved them to my python working directory and built them with javac there.
Once I had .class files of my java classes, I could call
tester = JClass('SoundTester') with no problem whatsoever.
Hope this helps someone else.

JNI "The specified procedure could not be found" when dependent library is linked

Following is the basic working structure:
MainProxy.dll ==> JNIClient.java
Using JNI, I have successfully loaded the MainProxy.dll and able to call the native functions. Following is the required structure:
Main.dll ==> MainProxy.dll ==> JNIClient.java
But when MainProxy.dll compiled and linked with another DLL Main.dll the System.loadLibrary("MainProxy"); call crashed with an exception
Exception in thread "AWT-EventQueue-0" java.lang.UnsatisfiedLinkError: MainProxy.dll: The specified procedure could not be found
However, the MainProxy.dll is successfully compiled and linked against Main.lib and both DLLs are placed to gather with java.
Any idea what causes this issue and how it can be resolved?
Above is the snap from dependencywalker. The ISPVPLPR.dll is the Main.dll and LPRPROXY.DLL is the MainProxy.dll. And the linking between these two looks fine. The CreateNativeClass is exported along with other functions from ISPVPLPR.dll while only CreateNativeClass is imported in LPRPROXY.dll.
Above snap shows that exported native function from LPRProxy.dll
Finally, it turns out that OpenCV pre-compiled libraries was the issue. The ISPVPLPR.DLL was utilizing OpenCV and the copied DLLs were the default that came with setup and were compiled for WinXP Prof 64bit or Win2003 64bit. Since Opencv_Core241.dll requires RtlLookupFunctionEntry and RtlVirtualUnwind functions from Kernel32.dll and these functions were only provided for WinXP and Win2003 Kernel32.dll versions (MSDN Reference).
The solution was simple to recompile the OpenCV2.4.1 for Win7 and with GOD blessings it worked.
I recommend you to use Dependency Walker from microsoft. Use this utility to really check if MainProxy.dll is correctly linked with Main.dll.
If Dependency Walker shows you a problem, tell us how do you compiled and linked MainProxy.dll.
When Dependency Walker shows you no problem, you won't have anymore an java.lang.UnsatisfiedLinkError

Calling dynamic library method - IntelliJ IDEA project - Java

I have the following Java native function
private static native void fillEnergyArrays(double currentTemp, double concNA, double concMG);
The function is implemented in C. The code has been tested and I have created a working dynamic library, libhyfiModel.jnilib, which I can use to call the method from a Java file, Temp.java. There are no problems in this case when I run the program with the one file. The method call works and returns the expected value.
The problem:
I am taking Temp.java and libhyfiModel.jnilib and trying to import them into a large IntelliJ IDEA project which uses Maven as a build manager. I have put my libhyfiModel.jnilib file in my correct directory so it loaded when the program executes. I double checked that it's loaded using this code in Temp.java:
static {
try {
System.loadLibrary("hyfiModel");
}
catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load\n" + e);
}
}
No exception is thrown here, so libhyfiModel.jnilib is found and loaded correctly, but when the native method is executed I get the following error:
Exception in thread "main" java.lang.UnsatisfiedLinkError: ca.virology.baseByBase.DiffEditor.fillEnergyArrays(DDD)V
at ca.virology.baseByBase.DiffEditor.fillEnergyArrays(Native Method)
at ca.virology.baseByBase.DiffEditor.main(DiffEditor.java:266)
I have looked at the documentation here https://www.jetbrains.com/idea/help/configuring-module-dependencies-and-libraries.html and followed the instructions with no success.
So the dynamic library is being loaded and I have added the directory containing libhyfiModel.jnilib as a dependency but the method can not execute... What am I missing?
EDIT:
I created a new IntelliJ project with just Temp.java and I am able to call the native function with no errors, so I'm thinking there must be a problem with my project configurations. Any IntelliJ experts out there?
Figured it out. It wasn't a configuration error since the library was being loaded properly. The problem was with Temp.java package membership used in the IntelliJ project.
I had a Temp.h file that was generated using the command javah -jni Temp that contains the C function definitions for my native functions.
I didn't realize that the native function definitions in Temp.h are different when the Java file Temp.java has a specified package.
I found my answer at Another JNI, C++, DLL, UnsatisfiedLinkError <Native Method>
It is shown that the header files' function names change with package membership.

Can't load personal dll with jna from netbeans

I'm using netbeans 7.4 / jdk 1.7u51
I downloaded the jar for JNA from official site, in version 4.0.0.
I have an internally developped DLL whose interface is in plain C, which loads perfectly well with ctypes in python. This dll is compiled in release with visual 2010, whose runtime are in path.
D:\fl006\Downloads>dir D:\deploy\SpotLight\spotlight-1488\PasanBusLibrary.dll
Directory of D:\deploy\SpotLight\spotlight-1488
29.01.2014 11:13 1'690'112 PasanBusLibrary.dll
I tried to load it in java with jna:
public interface CLibrary extends Library {
(...snip...)
void pasanIpcInitializeLibrary(String xClient, String xBusName, int xTimeout);
void pasanIpcTerminateLibrary();
}
public static void main(String[] args) {
NativeLibrary.addSearchPath("PasanBusLibrary","D:\\deploy\\SpotLight\\spotlight-1488");
CLibrary Bus = (CLibrary) Native.loadLibrary("PasanBusLibrary",CLibrary.class);
(... snip ...)
This is basically an out of the book standard dll load, from a custom location.
When activating jna debug, I see the following :
run:
Looking in classpath from sun.misc.Launcher$AppClassLoader#714a8f44 for /com/sun/jna/win32-x86-64/jnidispatch.dll
Found library resource at jar:file:/D:/code/perso/TestWrapperBus/jna-4.0.0.jar!/com/sun/jna/win32-x86-64/jnidispatch.dll
Looking for library 'PasanBusLibrary'
Adding paths from jna.library.path: null
Trying D:\deploy\SpotLight\spotlight-1488\PasanBusLibrary.dll
Adding system paths: []
Trying D:\deploy\SpotLight\spotlight-1488\PasanBusLibrary.dll
Looking for lib- prefix
Trying libPasanBusLibrary.dll
Looking in classpath from sun.misc.Launcher$AppClassLoader#714a8f44 for PasanBusLibrary
Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library 'PasanBusLibrary': Native library (win32-x86-64/PasanBusLibrary.dll) not found in resource path ([file:/D:/code/perso/TestWrapperBus/jna-4.0.0.jar, file:/D:/code/perso/TestWrapperBus/jna-platform-4.0.0.jar, file:/D:/code/perso/TestWrapperBus/build/classes/])
at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:271)
at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:398)
at com.sun.jna.Library$Handler.<init>(Library.java:147)
at com.sun.jna.Native.loadLibrary(Native.java:412)
at com.sun.jna.Native.loadLibrary(Native.java:391)
at testwrapperbus.TestWrapperBus.main(TestWrapperBus.java:39)
It looks it looks through the location I gave and somehow discards it. I tried different folders and I got same behaviour, there is no obvious file system right issue (dll is RW from all users)
Any clue on what I'm missing, I'm kind of stuck currently...
EDIT
if I load "msvcrt" this is working nice to cll printf
my dll has some dependencies, all of them hosted in c:\windows\system32 (standard runtime, dynamically linked)
My dll is a win32 compilation while I use a win64 JDK / JRE. Of course, when dealing with pure java, we don't care but loading native library needs to match.
I tried running from command line on a 32 bits JRE7 and it worked, so I'm pretty sure that installing JDK for win32 in my netbeans or recompiling my dll in 64 bits will solve the issue.
Thanks to this answer : Trying to use DLL from Java (JNA). Unable to load library exception for having put me on the righteous path

Mac + jni + java

A little background:
I have a java application that needs to talk to a third party hardware on mac. They have given me the sdk but it is not in Java. So I am trying to make jnilib that will act as a bridge between my java application and the SDK.
The issue:
I have made a small sample jnilib that talks to the SDK but when I try to use it in my java program I get the following error
Exception in thread "main" java.lang.UnsatisfiedLinkError: /Users/john.doe/Desktop/eclipse/workspace/Lesson13_Jni_Smart7/bin/libSmartTest7.jnilib: Library not loaded: build/Release/SMARTResponseSDK.framework/Versions/A/SMARTResponseSDK Referenced from: /Users/john.doe/Desktop/eclipse/workspace/Lesson13_Jni_Smart7/bin/libSmartTest7.jnilib
Reason: image not found
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1827)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1742)
at java.lang.Runtime.loadLibrary0(Runtime.java:823)
at java.lang.System.loadLibrary(System.java:1045)
at com.learning.lesson13.JniSmart7.<clinit>(JniSmart7.java:6)
From the error it looks like my libSmartTest7.jnilib is looking for the library SMARTResponseSDK.
What I have tried
I know where the library SMARTResponseSDK is on my Mac. I tried copying it over to my working folder in eclipse but I still get the error. I have tried using the -DJava.library.path but I still get the error.
Any ideas on what the best possible approach would be.
Once you are inside JNI code, it no longer matters what java.library.path points at.
Once you are inside JNI code, all you can do is to make sure library is visible to your code via LD_LIBRARY_PATH/DYLD_LIBRARY_PATH, or you can dynamically load your library file from any location you like.
So, for you, I suggest to take a look here:
dynamic loading of library in JNI - http://jnicookbook.owsiak.org/recipe-No-018/
Calling code from shared library (adapter pattern) - http://jnicookbook.owsiak.org/recipe-No-023/
You can also benefit from compilation flags while building your JNI library and use rpath.

Categories

Resources