java.lang.UnsatisfiedLinkError [modified]
-
Good day, I am trying to get a third party DLL to work in java (FWIW, I am using Netbeans 7.0). I am aware that getting third party DLLS to work (especially if it's not a C/C++ type DLL), is not an easy feat, and that you should use JNI to accomplish this. Like you guys know, following the JNI path will result in a wrapper for your DLL, which is exactly what I need. I will provide my code for both the C++ section as well as the Java section, and then the error message I receive will follow that. Please do note: I used javah to create the header file (see below) for the java file below. TestVC_OmniIDE
#include <windows.h>;
#include <stdio.h>;
#include "TestProgram.h"#pragma once
using namespace System;
namespace TestVC_OmniIDE {
BOOL WINAPI TestVC\_OmniIDEMain(HANDLE hHandle, DWORD dwReason, LPVOID lpReserved) { return TRUE; } JNIEXPORT void JNICALL Java\_TestProgram\_UpdateTextFile(JNIEnv \*, jclass) { printf("Hello world from VC++ DLL"); }
}
TestProgram.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class TestProgram */#ifndef _Included_TestProgram
#define _Included_TestProgram
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: TestProgram
* Method: UpdateTextFile
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_TestProgram_UpdateTextFile
(JNIEnv *, jclass);#ifdef __cplusplus
}
#endif
#endifTestProgram.java
class TestProgram
{
public static native void UpdateTextFile();
public static void main(String args[])
{
System.out.println("Hallo from main");
}
}Java Code to Call JNI Wrapper
public class OmniText {
static
{
System.loadLibrary("TestVC_OmniIDE");
}public native void UpdateTextFile();
}
Here is where I call the native method
OmniText omni = new OmniText();
omni.UpdateTextFile();As you can see, this is only a test, but as soon as this will be successful, I will create a production version taking parameters and returning a value. I know that the wrapper can be found, because, if I change the name of the wrapper file, it tells me that the file cannot be found. Now for the error (which can be identified from the post subject):
Exception in thread "AWT-EventQueue-0" java.lang.UnsatisfiedLinkErro
Where is the DLL? Make sure it is in the same folder as the .jar. Alternatively make sure you declare it in the JVM launch arguments[^].
Panic, Chaos, Destruction. My work here is done. Drink. Get drunk. Fall over - P O'H OK, I will win to day or my name isn't Ethel Crudacre! - DD Ethel Crudacre I cannot live by bread alone. Bacon and ketchup are needed as well. - Trollslayer Have a bit more patience with newbies. Of course some of them act dumb - they're often *students*, for heaven's sake - Terry Pratchett
-
Good day, I am trying to get a third party DLL to work in java (FWIW, I am using Netbeans 7.0). I am aware that getting third party DLLS to work (especially if it's not a C/C++ type DLL), is not an easy feat, and that you should use JNI to accomplish this. Like you guys know, following the JNI path will result in a wrapper for your DLL, which is exactly what I need. I will provide my code for both the C++ section as well as the Java section, and then the error message I receive will follow that. Please do note: I used javah to create the header file (see below) for the java file below. TestVC_OmniIDE
#include <windows.h>;
#include <stdio.h>;
#include "TestProgram.h"#pragma once
using namespace System;
namespace TestVC_OmniIDE {
BOOL WINAPI TestVC\_OmniIDEMain(HANDLE hHandle, DWORD dwReason, LPVOID lpReserved) { return TRUE; } JNIEXPORT void JNICALL Java\_TestProgram\_UpdateTextFile(JNIEnv \*, jclass) { printf("Hello world from VC++ DLL"); }
}
TestProgram.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class TestProgram */#ifndef _Included_TestProgram
#define _Included_TestProgram
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: TestProgram
* Method: UpdateTextFile
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_TestProgram_UpdateTextFile
(JNIEnv *, jclass);#ifdef __cplusplus
}
#endif
#endifTestProgram.java
class TestProgram
{
public static native void UpdateTextFile();
public static void main(String args[])
{
System.out.println("Hallo from main");
}
}Java Code to Call JNI Wrapper
public class OmniText {
static
{
System.loadLibrary("TestVC_OmniIDE");
}public native void UpdateTextFile();
}
Here is where I call the native method
OmniText omni = new OmniText();
omni.UpdateTextFile();As you can see, this is only a test, but as soon as this will be successful, I will create a production version taking parameters and returning a value. I know that the wrapper can be found, because, if I change the name of the wrapper file, it tells me that the file cannot be found. Now for the error (which can be identified from the post subject):
Exception in thread "AWT-EventQueue-0" java.lang.UnsatisfiedLinkErro
1. I don't think you should be putting your native code inside namespaces. 2. You have defined your native method in TestProgram.java inside the
TestProgram
class, but then you have a second definition insideOmniText
class. You do not actually call the native code anywhere in the code samples you have shown.The best things in life are not things.
-
1. I don't think you should be putting your native code inside namespaces. 2. You have defined your native method in TestProgram.java inside the
TestProgram
class, but then you have a second definition insideOmniText
class. You do not actually call the native code anywhere in the code samples you have shown.The best things in life are not things.
-
1. I don't think you should be putting your native code inside namespaces. 2. You have defined your native method in TestProgram.java inside the
TestProgram
class, but then you have a second definition insideOmniText
class. You do not actually call the native code anywhere in the code samples you have shown.The best things in life are not things.
I have included point 2 in my question (I accidentally omitted this when I was writing the question), but thanks for pointing that out. I should add that I used VC++ to create the header, which would explain the namespace and the pragma. Also, I have numerous packages inside this application, and I have read that you should make the package of the wrapper to be the same as your package, which is a bit confusing, since I have quite a lot of packages. PS, I have just now removed the System namespace, and still gives the same error as described in the question.
-
I have included point 2 in my question (I accidentally omitted this when I was writing the question), but thanks for pointing that out. I should add that I used VC++ to create the header, which would explain the namespace and the pragma. Also, I have numerous packages inside this application, and I have read that you should make the package of the wrapper to be the same as your package, which is a bit confusing, since I have quite a lot of packages. PS, I have just now removed the System namespace, and still gives the same error as described in the question.
I still do not think that your CPP code should be included in a namespace; also you have a
#pragma
statement in your source which should be removed. You have defined your C function inside two different classes in your java source, and then tried to call it from the wrong class (it belongs to classTestProgram
).RossouwDB wrote:
I should add that I used VC++ to create the header, which would explain the namespace and the pragma.
I don't see how this statement holds true; the header file should be created by the
javah
command. I just tried a sample and it did not include any namespace information.The best things in life are not things.
-
I still do not think that your CPP code should be included in a namespace; also you have a
#pragma
statement in your source which should be removed. You have defined your C function inside two different classes in your java source, and then tried to call it from the wrong class (it belongs to classTestProgram
).RossouwDB wrote:
I should add that I used VC++ to create the header, which would explain the namespace and the pragma.
I don't see how this statement holds true; the header file should be created by the
javah
command. I just tried a sample and it did not include any namespace information.The best things in life are not things.
Richard MacCutchan wrote:
I don't see how this statement holds true;
Your quite right. TestVC_OmniIDE was done using VC++, thus giving the pragma and namespaces.
Richard MacCutchan wrote:
it belongs to class
TestProgram
This seems to have been the problem. I have found a fix, thanks to your help. This is what I had done that resulted in the error I created this "TestProgam" to test everything out, and have immediately put the code into my big application (which is not TestProgram). This explained the error that I have received. After reading what you said above, I ran TestProgram.java and it worked. Now, I will convert this "TestProgram" to a class (or maybe a separate .jar) and use this within my big application, which should work. Thanks again for your help, it is much appreciated! Kind regards, Rossouw
-
Richard MacCutchan wrote:
I don't see how this statement holds true;
Your quite right. TestVC_OmniIDE was done using VC++, thus giving the pragma and namespaces.
Richard MacCutchan wrote:
it belongs to class
TestProgram
This seems to have been the problem. I have found a fix, thanks to your help. This is what I had done that resulted in the error I created this "TestProgam" to test everything out, and have immediately put the code into my big application (which is not TestProgram). This explained the error that I have received. After reading what you said above, I ran TestProgram.java and it worked. Now, I will convert this "TestProgram" to a class (or maybe a separate .jar) and use this within my big application, which should work. Thanks again for your help, it is much appreciated! Kind regards, Rossouw
-
In the posted code but since they posted a link error from the native method the real code is calling it.