Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > dlopen() within a JNI-callable C++ function on Solaris?

Reply
Thread Tools

dlopen() within a JNI-callable C++ function on Solaris?

 
 
Steve Gilbert
Guest
Posts: n/a
 
      04-13-2004
Hello,

I have a set of JNI-callable C++ routines in lib1.so,
From within one of these I would like to dlopen() a second
C++ library lib2.so.

dlopen() of this' second library always fails, with dlerror()
reporting
'ld.so.1: java: fatal: JNI_OnLoad: can't find symbol'

This second library is purely for local use within a single
JNI-callable routine. Example code below.

How can I make this work please?

Thanks
-- Steve

sun01% java -version
java version "1.4.2_04"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_04-b05)
Java HotSpot(TM) Client VM (build 1.4.2_04-b05, mixed mode)

sun01% CC -V
CC: Forte Developer 7 C++ 5.4 2002/03/09


sun01% more Jmaster.java
import java.util.*;

public class Jmaster
{
static
{
System.loadLibrary("lib1");
};

private native void lib1doit();

public static void main(String[] dummy)
{
Jmaster me = new Jmaster();
me.lib1doit();
}
}

sun01% more liblib1.cpp
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <link.h>
#include <errno.h>

#include "Jmaster.h"

JNIEXPORT void JNICALL Java_Jmaster_lib1doit(JNIEnv* env, jobject obj)
{
char* dlerr;

fprintf(stderr,"Loaded liblib1.so from Java, about to dlopen
liblib2.so\n");

// Open lib2

void* mydll = dlopen("liblib2.so",RTLD_NOW);
if ((dlerr=dlerror()) != NULL)
{
fprintf(stderr,"ERROR! dlopen of liblib2 failed: %s\n",dlerr);
exit(-1);
};

// Get call to 'lib2doit()'
void(*doit2)() = (void(*)()) dlsym(mydll,"lib2doit");
if ((dlerr=dlerror()) != NULL)
{
fprintf(stderr,"ERROR! dlsym of lib2doit failed: %s\n",dlerr);
exit(-1);
};

// Call 'doit2()'
doit2();

// Close lib2

dlclose(mydll);
if ((dlerr=dlerror()) != NULL)
{
fprintf(stderr,"ERROR! dlclose of liblib2 failed: %s\n",dlerr);
exit(-1);
};
};


sun01% more liblib2.cpp
#include <stdio.h>

extern "C" void lib2doit()
{
fprintf(stderr,"HELLO from lib2\n");
}

sun01% javac Jmaster.java
sun01% javah -jni Jmaster
sun01% CC -G liblib1.cpp -o liblib1.so -xildoff -library=Cstd
-features=no%strictdestrorder -ldl -I/usr/j2sdk1.4.2/include
-I/usr/j2sdk1.4.2/include/solaris
sun01% CC -G liblib2.cpp -o liblib2.so -xildoff -library=Cstd
-features=no%strictdestrorder
sun01%
sun01% java Jmaster
Loaded liblib1.so from Java, about to dlopen liblib2.so
ERROR! dlopen of liblib2 failed: ld.so.1: java: fatal: JNI_OnLoad:
can't find symbol
sun01%
 
Reply With Quote
 
 
 
 
Gordon Beaton
Guest
Posts: n/a
 
      04-14-2004
On 13 Apr 2004 03:55:40 -0700, Steve Gilbert wrote:
> I have a set of JNI-callable C++ routines in lib1.so,
> From within one of these I would like to dlopen() a second
> C++ library lib2.so.
>
> dlopen() of this' second library always fails, with dlerror()
> reporting
> 'ld.so.1: java: fatal: JNI_OnLoad: can't find symbol'


I don't know why the second library fails, but I'll offer some random
thoughts and maybe something will help.

- I see that you test the results of dlopen() by calling dlerror(),
but I wonder you aren't seeing the most recent error, and *not* the
results of your (possibly successful) call to dlopen(). The JVM has
recently attempted to find (optional) JNI_OnLoad() in your first
library and doesn't care if it succeeded.

Check whether dlopen() returns NULL before you call dlerror(),
because maybe the library has actually loaded. (My manpage does say
that yours is the correct way to check whether dlsym() has failed
however).

- Does the second library have additional dependencies, or is it
really exactly the code you've posted? What does ldd say? Does nm
report any missing symbols?

- What happens if you use RTLD_LAZY instead? Does the error occur
later when you invoke the method?

- Perhaps you don't need to use dlopen() at all. You can invoke
functions directly in the second library, if when you build the
first library you tell the linker about its depedendencies on the
second one using linker options like "-f liblib2.so" to identify the
second library, and "-R /absolute/path" to add a runtime library
search path.

Hope this helps!

/gordon

--
[ 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
 
Reply With Quote
 
 
 
 
Steve Gilbert
Guest
Posts: n/a
 
      04-14-2004
Gordon Beaton <(E-Mail Removed)> wrote in message news:<407ce27e$(E-Mail Removed)>...
> On 13 Apr 2004 03:55:40 -0700, Steve Gilbert wrote:
> > I have a set of JNI-callable C++ routines in lib1.so,
> > From within one of these I would like to dlopen() a second
> > C++ library lib2.so.
> >
> > dlopen() of this' second library always fails, with dlerror()
> > reporting
> > 'ld.so.1: java: fatal: JNI_OnLoad: can't find symbol'

>
> I don't know why the second library fails, but I'll offer some random
> thoughts and maybe something will help.
>
> - I see that you test the results of dlopen() by calling dlerror(),
> but I wonder you aren't seeing the most recent error, and *not* the
> results of your (possibly successful) call to dlopen(). The JVM has
> recently attempted to find (optional) JNI_OnLoad() in your first
> library and doesn't care if it succeeded.
>
> Check whether dlopen() returns NULL before you call dlerror(),
> because maybe the library has actually loaded. (My manpage does say
> that yours is the correct way to check whether dlsym() has failed
> however).JNI_OnLoad()
>


Thank you, that was exactly it. The JVM had left an unread
message in dlerror() reporting that there was no JNI_OnLoad() in
the first library. I just needed to call dlerror() once at the
beginning of lib1 to clear that message and all was well.

-- Steve
 
Reply With Quote
 
Gordon Beaton
Guest
Posts: n/a
 
      04-14-2004
On 14 Apr 2004 08:57:47 -0700, Steve Gilbert wrote:
> Thank you, that was exactly it. The JVM had left an unread message
> in dlerror() reporting that there was no JNI_OnLoad() in the first
> library. I just needed to call dlerror() once at the beginning of
> lib1 to clear that message and all was well.


Or, you could define JNI_OnLoad() in lib1. That way, you can load lib2
as part of its initialization, and if that fails, let the error
propagate so the JVM "fails" to load lib1.

/gordon

--
[ 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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Can a function be called within a function ? Peter Moscatt Python 4 04-18-2005 09:33 PM
write a function such that when ever i call this function in some other function .it should give me tha data type and value of calling function parameter komal C++ 6 01-25-2005 11:13 AM
pointing to a member function/method within another function uli C++ 3 05-13-2004 11:02 AM
adding attributes to a function, from within the function Fernando Rodriguez Python 6 11-03-2003 05:04 PM
generator function within a generator function doesn't execute? TheDustbustr Python 1 07-25-2003 10:45 AM



Advertisments