Skip to main content



      Home
Home » Language IDEs » C / C++ IDE (CDT) » Another JNI UnsatisfiedLinkError
Another JNI UnsatisfiedLinkError [message #222937] Wed, 03 September 2008 13:21 Go to next message
Eclipse UserFriend
Originally posted by: dontreplyhere.inter.net

I know there are a lot of answers to this question, and I'm pretty sure all
the usual stuff (package name, location of the dll) is correct in my case.

I reduced the issue to a simple HelloWorld style problem and I fear I have
to a CDT problem, that's why I'm posting for help here.

I use the same .cpp file and javah generated .h file for a VisualStudio
project, which creates a DLL that works fine.
Creating that dll with latest Eclipse CDT and its built-in make (using
minGW)
creates a libMyLib.dll file, which can be loaded, but produces this

Exception in thread "main" java.lang.UnsatisfiedLinkError:
com.osisoft.JNITest.GetMessage()Ljava/lang/String;
at com.osisoft.JNITest.GetMessage(Native Method)
at com.osisoft.JNITest.main(JNITest.java:18)

The java code is:
-------------------------------------
package com.osisoft;
public class JNITest {
static String LibPathVS =
"D:\\MyDocuments\\Visual Studio
2008\\Projects\\JNITest\\Release\\JNITestLib.dll";
static String LibPathCDT =
" D:\\EclipseWorkspaceC_J\\JNITestLib\\Release\\libJNITestLib. dll ";
static {
//System.loadLibrary("JNITestLib");
System.load(LibPathCDT);
}
native String GetMessage();

public static void main(String[] args) {
JNITest t = new JNITest();
String s= t.GetMessage(); // fails here, but only with LibPathCDT
System.out.println(s);
}
}
----------------------------------------
I copied the method declaration from the generated include file and
implemented the c++ this way:
---------------------------------------
#include "com_osisoft_JNITest.h"
JNIEXPORT jstring JNICALL Java_com_osisoft_JNITest_GetMessage
(JNIEnv * env, jobject) {
return env->NewStringUTF("Hello from JNITestLib.dll");
}
---------------------------------------

All includes are fine, everything compiles and links without error, of
course:
----------------------------------------
**** Build of configuration Release for project JNITestLib ****
**** Internal Builder is used for build ****

g++ -ID:\EclipseWorkspaceC_J\JavaTest\Output
-IC:\Program Files\Java\jdk1.6.0_07\include
-IC:\Program Files\Java\jdk1.6.0_07\include\win32
-O0 -Wall -c -fmessage-length=0
-oJNITestLib.o ..\JNITestLib.cpp

g++ -shared -olibJNITestLib.dll JNITestLib.o

Build complete for project JNITestLib
----------------------------------------

The DLLs are there and the System.load() works well.
What else to observe ? Which setting did I miss?
Re: Another JNI UnsatisfiedLinkError [message #222976 is a reply to message #222937] Thu, 04 September 2008 04:43 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: 4cs6fcg02.sneakemail.com

Michael Hesselbach schreef:
> package com.osisoft;
> public class JNITest {
> static String LibPathVS =
> "D:\\MyDocuments\\Visual Studio
> 2008\\Projects\\JNITest\\Release\\JNITestLib.dll";
> static String LibPathCDT =
> " D:\\EclipseWorkspaceC_J\\JNITestLib\\Release\\libJNITestLib. dll ";
> static {
> //System.loadLibrary("JNITestLib");

On Windows, . is added to the path, such that if you execute this
program from the folder D:\MyDocuments\Visual Studio
2008\Projects\JNITest\Release, it will find JNITestLib.dll. It will,
however, not find the other one!

> System.load(LibPathCDT);
> }


> g++ -ID:\EclipseWorkspaceC_J\JavaTest\Output
> -IC:\Program Files\Java\jdk1.6.0_07\include
> -IC:\Program Files\Java\jdk1.6.0_07\include\win32
> -O0 -Wall -c -fmessage-length=0
> -oJNITestLib.o ..\JNITestLib.cpp

How do you specify the -I’s? Or does Eclipse do that for you?

> The DLLs are there and the System.load() works well.

I’d recommend using System.loadLibrary() and putting the dll in a
suitable place, or starting the jvm with
-Djava.library.path=/path/to/dll. You can also do this from the Eclipse
launch configuration editor.

H.
--
Hendrik Maryns
http://tcl.sfs.uni-tuebingen.de/~hendrik/
==================
Ask smart questions, get good answers:
http://www.catb.org/~esr/faqs/smart-questions.html
Re: Another JNI UnsatisfiedLinkError [message #223096 is a reply to message #222937] Thu, 04 September 2008 08:50 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: dontreplyhere.inter.net

Just in case it helps anyone else:

"Michael Hesselbach" wrote
>I know there are a lot of answers to this question, and I'm pretty sure all
> the usual stuff (package name, location of the dll) is correct in my
> case.
>
....
> g++ -shared -olibJNITestLib.dll JNITestLib.o
....
> What else to observe ? Which setting did I miss?

Finally I found the strange linker flag
-Wl,--kill-at
"to ensure that the __stdcall naming convention is used"
I added this to Project Properties --> C/C++ Build -->Settings
In the tab Tool Settings at MinGW C++ Linker --> Miscellaneous
there's an all-purpose Linker flags field, where it is really applied:

------------------------------------------------------------ ----
**** Internal Builder is used for build ****

g++ -Wl,--kill-at -shared -olibJNITestLib.dll JNITestLib.o
------------------------------------------------------------ ----
And the UnsatisfiedLinkError is gone !!!

What a strange thing:
IMO Eclipse CDT is not yet really helpful for Java JNI
( and initially I thought to even get mixed debugging for free ;)
Re: Another JNI UnsatisfiedLinkError [message #223103 is a reply to message #222976] Thu, 04 September 2008 12:08 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: dontreplyhere.inter.net

> How do you specify the -I's? Or does Eclipse do that for you?
>
You can, and should, add paths to the Eclipse environment.
Project properties --> C++ General --> Paths and symbols
They show up in the "includes" folder.

> I'd recommend using System.loadLibrary() and putting the dll in a
> suitable place, or starting the jvm with
> -Djava.library.path=/path/to/dll. You can also do this from the Eclipse
> launch configuration editor.
>
Sure, System.loadLibrary() is -finally- the recommended way, because
it's platform independent. But I wanted to be sure to easily switch to the
freshly generated dll and make sure not to be fooled by some library
searching mechanism (finding something I did not expect).
Thus I chose the full path and file extension. And, the dll was found
and loaded.

No, it was the missing -Wl,--kill-at (what an obscure syntax;)
MinGW linker option, which produced wrong method names ...

And CDT does not really help with this setting (or I did not find the
correct location but used C/C++ Build -->Settings
In the tab Tool Settings at MinGW C++ Linker --> Miscellaneous
there's an all-purpose Linker flags field

BTW: Thanks for your reply, Hendrik!
- M
Re: Another JNI UnsatisfiedLinkError [message #223164 is a reply to message #223103] Fri, 05 September 2008 06:32 Go to previous message
Eclipse UserFriend
Originally posted by: 4cs6fcg02.sneakemail.com

Michael Hesselbach schreef:
>> How do you specify the -I's? Or does Eclipse do that for you?
>>
> You can, and should, add paths to the Eclipse environment.
> Project properties --> C++ General --> Paths and symbols
> They show up in the "includes" folder.

Yes, but unfortunately, I am unable to let Eclipse generate the
makefiles since I use SWIG also.

Unless someone knows how to add additional targets to the
Eclipse-generated makefiles, in which case I might consider trying that.
And it should be cross-platform, of course.

>> I'd recommend using System.loadLibrary() and putting the dll in a
>> suitable place, or starting the jvm with
>> -Djava.library.path=/path/to/dll. You can also do this from the Eclipse
>> launch configuration editor.

> No, it was the missing -Wl,--kill-at (what an obscure syntax;)

Blame gcc.

> MinGW linker option, which produced wrong method names ...

Indeed, it is in the MinGW FAQ: http://www.mingw.org/node/41.
Specifically, it refers to http://www.mingw.org/node/41. I agree they
might stress the -Wl,--kill-at, since it is what makes the MinGW style
different from Linux. You could see that by comparing the usual
compilation options. (It’s what I did: I have one general makefile
which contains the common options and then three platform-dependent
makefiles which are included based on a shell escape to uname -a, and
which add platform-specific options.
For Linux:
# fPIC is necessary for the linker
CFLAGS += -fPIC

# create a shared library
LINKERFLAGS += -shared

For MinGW:
# create a shared library
LINKERFLAGS += -shared
# MinGW needs some extra linker flags, see
http://www.mingw.org/mingwfaq.shtml#faq-jni-dll
LINKERFLAGS += -D_JNI_IMPLEMENTATION_ -Wl,--kill-at

For Mac (OS X):
# fPIC is necessary for the linker, arch for Mac
CFLAGS += -fPIC -arch x86_64

# create a shared library
LINKERFLAGS += -bundle
# extra linker flags for Mac
LINKERFLAGS += -arch x86_64 -framework JavaVM

Additionally, they define the name of the library and the jdk include
paths.)


> And CDT does not really help with this setting (or I did not find the

I had similar trouble trying to compile a JNI jar on Linux: the Eclipse
makefile did not include -fPIC, which made the lib unusable. Similarly,
you’d expect it to include -Wl,--kill-at if you compile a shared library
with MinGW. Or at least ask you whether you want it, since I think
non-Java libraries might not need it.

Cheers, H.
--
Hendrik Maryns
http://tcl.sfs.uni-tuebingen.de/~hendrik/
==================
Ask smart questions, get good answers:
http://www.catb.org/~esr/faqs/smart-questions.html
Previous Topic:Software update problem in Eclipse Platform
Next Topic:org.eclipse.ant.AntBuilderLaunchConfigurationType does not exist
Goto Forum:
  


Current Time: Tue May 06 12:05:28 EDT 2025

Powered by FUDForum. Page generated in 0.04650 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top