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 / Virtual Machine / February 2004

Tip: Looking for answers? Try searching our database.

jni - problems when loading shared library

Thread view: 
Damjan - 19 Feb 2004 10:28 GMT
Hi guys I need some help. I've made a little program written in c that
compiles well with gcc. After compiling, i created a shared library with
ld, without any problems again. But, when trying to load the library from a
java code, i get an error saying:

Exception in thread "main" java.lang.UnsatisfiedLinkError:
/home/damjan/jbproject/progetto/classes/progetto/libfasta.so:
/home/damjan/jbproject/progetto/classes/progetto/libfasta.so: undefined
symbol: _ZNSaIcEC1Ev
       at java.lang.ClassLoader$NativeLibrary.load(Native Method)
       at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1560)
       at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1485)
       at java.lang.Runtime.loadLibrary0(Runtime.java:788)
       at java.lang.System.loadLibrary(System.java:834)
       at progetto.Mojpanel.<clinit>(Mojpanel.java:20)

Here is my code:

#include <jni.h>
#include "Frame1.h"
#include <cstring>
#include <fstream>
#include <iostream>

#include "c++/Biosequence.h"

extern "C" {
using namespace std;
JNIEXPORT void JNICALL Java_Frame1_fasta (JNIEnv *env, jobject obj, jstring
fastaname) {
   Biosequence* s;
   const char *name = env->GetStringUTFChars(fastaname, 0);
   string fastapath = "";
   fastapath = name;
   ifstream fin(fastapath.c_str());
   if (!fin.is_open()) {
     cout << "Unable to open " << fastapath << endl;
     exit(1);
   }
   s = new Biosequence(fin);
   fin.close();
   cout << s->getInfo() << endl;
   s->setName(fastapath);
   s->buildSuffixTree(SuffixTree::LAZY_STRATEGY);
   env->ReleaseStringUTFChars(fastaname, name);
   printf("Funzionaaaaaa!!\n");
 }
} // end extern "C"

One more thing:
I tried to see some details of the library created with the linux comand nm,
and realize that that probably the part of the code which is problematic
is: std::allocator<char>::allocator() but i don't know why. Maybe for some
string - char incompatibility.

P.S. I'm working on JBuilderX under Mandrake Linux 9.2 with jdk 1.4
P.P.S. I tried to make an equivalent selfstanding program in c without jni
features, and it worked fine. Probably
Gordon Beaton - 19 Feb 2004 10:55 GMT
> After compiling, i created a shared library with ld, without any
> problems again. But, when trying to load the library from a java
[quoted text clipped - 4 lines]
> /home/damjan/jbproject/progetto/classes/progetto/libfasta.so: undefined
> symbol: _ZNSaIcEC1Ev

Specify -lstdc++ when you link your shared library.

If you'd linked using gcc (g++) instead of ld (as is usually
recommended these days), I believe this would have been done for you.

/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

Damjan - 19 Feb 2004 12:57 GMT
>> After compiling, i created a shared library with ld, without any
>> problems again. But, when trying to load the library from a java
[quoted text clipped - 11 lines]
>
> /gordon

I still didn't get it... sorry but I'm a newbie in this.
How can I make a shared library libxxx.so with gcc?
Now I'm using gcc only to compiling, like this:
  gcc -I/home/damjan/JBuilderX/jdk1.4/include
-I/home/damjan/JBuilderX/jdk1.4/include/linux -c Unifier.cpp
and after that
  ld -shared -o libfasta.so Unifier.o
to create a library 'libfasta'.
and when I tried to link with '-l stdc++' or '-lstdc' I got this:
[damjan@localhost progetto]$ ld -l stdc++ -shared -o libfasta.so Unifier.o
ld: cannot find -lstdc++

Damjan
Gordon Beaton - 19 Feb 2004 15:25 GMT
> I still didn't get it... sorry but I'm a newbie in this.
> How can I make a shared library libxxx.so with gcc?

 gcc -fPIC -D_REENTRANT -I [...] -c Unifier.cpp
 gcc Unifier.o -o libfasta.so -lstdc++

/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

Gordon Beaton - 19 Feb 2004 15:57 GMT
On 19 Feb 2004 16:25:41 +0100, I wrote:
>   gcc -fPIC -D_REENTRANT -I [...] -c Unifier.cpp
>   gcc Unifier.o -o libfasta.so -lstdc++

Sorry:

 gcc -shared Unifier.o -o libfasta.so -lstdc++

/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

Matthias - 25 Feb 2004 20:14 GMT
Hi Guys!

I have nearly the same problem!
I want to write a Java-Wrapper for a C++-Library! Ok, i have read some
JNI-Tuts, and some simple testing-programs worked fine!

Ok, i will post some code-referneces, because i think, its the best
way to explain my problem!

Note: the C++-Library is known as 'Irrlicht'!

The header file for the whole (jni).c files is:
#include <jni.h>
#include <irrlicht.h>

#pragma comment(lib, "Irrlicht.lib")

I compile the (jni).c files with the following Makefile:
OPTS = -I $(JAVA_HOME)/include -I $(JAVA_HOME)/include/linux
-I"$HOME/irrlicht/include" -I"/usr/X11R6/include" -L"/usr/X11R6/lib"
-L"$HOME/irrlicht/lib/Linux" -lIrrlicht -lGL -lXxf86vm -lXext -lX11
-lz -ljpeg

all:
    $(CXX) -fPIC -lstdc++ -shared  $(OPTS) "(jni).cpp-files" -o
my_library.so

(-lGL -lXxf86vm -lXext -lX11 -lz -ljpeg is needed by the
Irrlicht-library!!!!)

Ok, i get the following error, when i want to start the java-program:
Exception in thread "main" java.lang.UnsatisfiedLinkError:
$HOME/my_library.so: $HOME/my_library.so: undefined symbol:
_ZN3irr12createDeviceENS_5video11EDriverTypeERKNS_4core11dimension2dIiEEjbbPNS_14IEventReceiverEPKw
    at java.lang.ClassLoader$NativeLibrary.load(Native Method)
    at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1560)
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1456)
    at java.lang.Runtime.load0(Runtime.java:737)
    at java.lang.System.load(System.java:811)
    at Main.<clinit>(Main.java:31)

When i type "nm -f my_library.so" in the console i get the following
error:
        w __cxa_finalize@@GLIBC_2.1.3
        w __gmon_start__
        U __gxx_personality_v0@@CXXABI_1.2
        w _Jv_RegisterClasses
        U _ZN3irr12createDeviceENS_5video11EDriverTypeERKNS_4core11dimension2dIiEEjbbPNS_14IEventReceiverEPKw

I don't know why the function is so "crypted" but it means, that the
problem is happening, when calling the function
createDevice(EDriverType, dimension2d<32>(w, h), etc.)

Ok, i hope you can help me, and if you need further information i will
post them!!

thanks in advange!
matthias
Gordon Beaton - 26 Feb 2004 07:29 GMT
> Ok, i get the following error, when i want to start the java-program:
> Exception in thread "main" java.lang.UnsatisfiedLinkError:
[quoted text clipped - 6 lines]
>     at java.lang.System.load(System.java:811)
>     at Main.<clinit>(Main.java:31)

[...]

> I don't know why the function is so "crypted" but it means, that the
> problem is happening, when calling the function
> createDevice(EDriverType, dimension2d<32>(w, h), etc.)

Is createDevice() a native method declared in your Java class, and
defined in the library?

To prevent the C++ compiler from mangling the symbol name, your native
method *must* be declared with: extern "C"

This is done automatically for you if you include the header file
generated by javah *and* your functions use the exact names and
signatures found in that file. If you changed any of the names or
argument types (don't!) the declaration in the generated header file
isn't sufficient and you need to add the declaration yourself to the
function definition.

If that doesn't help, post the contents of the generated header and
relevant parts of the native code.

Note too that when you link, you should normally put the library flags
(-lstdc++ etc) *after* the object files and other libraries that
depend on them. See:

 http://gcc.gnu.org/onlinedocs/gcc-3.3.2/gcc/Link-Options.html

/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

Matthias - 26 Feb 2004 18:57 GMT
Hi!

Thanks for you quick answer!
The header-file looks like this:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class jirr_Jirr */

#pragma comment(lib, "Irrlicht.lib")

#ifndef _Included_jirr_Jirr
#define _Included_jirr_Jirr
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class:     jirr_Jirr
* Method:    cpp_createDevice
* Signature: (IIIIZZLjirr/JiEventReceiver;)Ljirr/JiDevice;
*/
JNIEXPORT jobject JNICALL Java_jirr_Jirr_cpp_1createDevice
 (JNIEnv *, jclass, jint, jint, jint, jint, jboolean, jboolean,
jobject);

#ifdef __cplusplus
}
#endif
#endif

and the corresponding cpp-file is:
#include "jirr_Jirr.h"
#include <irrlicht.h>
using namespace irr;

using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

JNIEXPORT jobject JNICALL Java_jirr_Jirr_cpp_1createDevice (JNIEnv
*env, jclass cls, jint type, jint width, jint height, jint bits,
jboolean fullscreen, jboolean stencilbuffer, jobject receiver) {

    IrrlichtDevice *device;

    device = createDevice(type, dimension2d<s32>((s32)width,
(s32)height), (u32)bits, (bool)fullscreen, (bool)stencilbuffer, 0);
    // here, java crashes!!!

    return (jobject)device;   //only for testing

}

I cant find any mistake!

Thanks in advange!!!
matthias
Juergen Kreileder - 26 Feb 2004 20:12 GMT
[...]

> I cant find any mistake!

Read Gordon's last hint again

,----
| Note too that when you link, you should normally put the library flags
| (-lstdc++ etc) *after* the object files and other libraries that
| depend on them. See:
|
|   http://gcc.gnu.org/onlinedocs/gcc-3.3.2/gcc/Link-Options.html
`----

and change

,----
| OPTS = -I $(JAVA_HOME)/include -I $(JAVA_HOME)/include/linux
| -I"$HOME/irrlicht/include" -I"/usr/X11R6/include" -L"/usr/X11R6/lib"
[quoted text clipped - 4 lines]
|     $(CXX) -fPIC -lstdc++ -shared  $(OPTS) "(jni).cpp-files" -o
| my_library.so
`----

to something like

,----
| CXX_FLAGS = -D_REENTRANT -I $(JAVA_HOME)/include
| -I $(JAVA_HOME)/include/linux -I"$HOME/irrlicht/include"
[quoted text clipped - 6 lines]
|     $(CXX) -fPIC -shared $(CXX_FLAGS) "(jni).cpp-files" -o
| my_library.so $(LD_FLAGS)
`----

       Juergen

Signature

Juergen Kreileder, Blackdown Java-Linux Team
http://www.blackdown.org/java-linux/java2-status/

Matthias - 29 Feb 2004 12:40 GMT
Thank you very much Gordon and especially Juergen!
Now i can continue my work!

bye,
Matthias!


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.