Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / May 2005

Tip: Looking for answers? Try searching our database.

JNI Unsatisfied Link Error (but the method name is correct!)

Thread view: 
cppaddict - 20 May 2005 02:07 GMT
When I've gotten unsatisfied link errors before when calling native
methods, it's usually been because the mathod name had been changed in
the Java file, but not updated in the JNI header (and the DLL
recompiled using the new header).

This time, though, the names seemed to be correct.

My java method (part of the Engine class in the package blackjack)
looks like:

public native void init(String windowTitle);

My C JNI method stub look like:

JNIEXPORT void JNICALL Java_blackjack_Engine_init(JNIEnv *, jobject,
jstring);

The DLL compiles without error, and is being loaded without error (in
a static block). What else could be causing the unsatisifed link
error?

TIA,
cpp
Gordon Beaton - 20 May 2005 08:03 GMT
> My java method (part of the Engine class in the package blackjack)
> looks like:
[quoted text clipped - 9 lines]
> (in a static block). What else could be causing the unsatisifed link
> error?

There are two things that cause UnsatisfiedLinkError. One is when
System.loadLibrary() fails to load the library, the other is when the
JVM fails to find a specific method in the library. The text of the
error message itself will indicate which is the case, but you've
already indicated that the library loads ok.

The JVM will fail to find a method in the library for various reasons,
but essentially they all point to the same thing: that a method with
the specified name was not found. Realize that the compiler itself
sometimes does things with the symbol names unless you tell it not to,
and this will prevent the JVM from finding the method, even though
you've named them correctly.

Examine the library contents, for example with objdump or nm (on unix)
or dumpbin or quickview (on windows) to see what's there.

Here are some things that can cause the symbols in the library to be
different from your source code:

- you are compiling with a C++ compiler, and it has mangled the symbol
 names because you failed to declare your native methods with extern
 "C". If you included the header file generated by javah (which you
 should), and your signatures *exactly* match those in the header
 file generated by javah (which they should), then then this has
 already been done for you. If that isn't the case, why not?

- your compiler has added extra information to the symbol names such
 as @8 or @12. There should be a compiler option to prevent that (for
 gcc, try -Wl,--kill-at).

/gordon

Signature

[  do not email me copies of your followups  ]
g o r d o n + n e w s @  b a l d e r 1 3 . s e

cppaddict - 20 May 2005 11:29 GMT
Gordon,

Thanks for your reply.

>Examine the library contents, for example with objdump or nm (on unix)
>or dumpbin or quickview (on windows) to see what's there.

Opening the .dll in depends.exe confirms that the names have been
mangled (or decorated), despite my using the javah generated header
file (which includes the extern C directive).  Any idea why this is
happening?  I compiled with Borland, and I have successfully used
Borland-compiled DLLs with JNI before.  In any case, I cannot find any
compiler option do suppress the mangling, despite lots of google and
help searching.

Any other advice?

Thanks,
cpp
Gordon Beaton - 20 May 2005 12:13 GMT
> Opening the .dll in depends.exe confirms that the names have been
> mangled (or decorated), despite my using the javah generated header
> file (which includes the extern C directive). Any idea why this is
> happening?

Why don't you post a real example of what the symbols look like in the
dll.

If you mean C++ decorated, it's because your methods don't exactly
match the declarations in the header file. You can declare the methods
themselves using extern "C" too, but the signatures really should
match the generated ones.

If you mean C decorated (@8, @12 etc), you could look for a linker
switch like --add-stdcall-alias, or define a link map to create
aliases for the symbols. Sorry I can't be more specific, I've never
programmed on windows and don't really know what is required. Maybe
someone who has can offer a concrete solution here.

Alternatively, you could call RegisterNatives() from JNI_OnLoad, which
lets you specify any names you like for the native methods. And since
you identify the methods by pointer, any name mangling should have no
effect.

/gordon

Signature

[  do not email me copies of your followups  ]
g o r d o n + n e w s @  b a l d e r 1 3 . s e

cppaddict - 20 May 2005 11:43 GMT
Gordon,

Just wanted to let you know that because of your post, I solved the
problem.   It turned out I had forgotten to include the header file in
my implementation file, so that the extern C directive was never
appearing.  Would never have noticed that if you hadn't narrowed down
the problem for me.  Thank you very, very much.

cpp


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.