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

Discussion in 'Java' started by Steve Gilbert, Apr 13, 2004.

  1. 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%
    Steve Gilbert, Apr 13, 2004
    #1
    1. Advertising

  2. 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
    Gordon Beaton, Apr 14, 2004
    #2
    1. Advertising

  3. Gordon Beaton <> wrote in message news:<407ce27e$>...
    > 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
    Steve Gilbert, Apr 14, 2004
    #3
  4. 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
    Gordon Beaton, Apr 14, 2004
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. ralph

    jni on solaris

    ralph, Aug 11, 2003, in forum: Java
    Replies:
    1
    Views:
    559
    Roedy Green
    Aug 11, 2003
  2. Tian

    JNI problem on Solaris 9

    Tian, Sep 3, 2003, in forum: Java
    Replies:
    5
    Views:
    525
    Sean Burke
    Sep 9, 2003
  3. exiquio
    Replies:
    2
    Views:
    524
    exiquio
    Oct 7, 2008
  4. Markku Linnoskivi
    Replies:
    2
    Views:
    489
    Peter
    Jan 17, 2012
  5. Ulrich Eckhardt
    Replies:
    6
    Views:
    101
    Peter Otten
    Jul 12, 2013
Loading...

Share This Page