smeerkahoven
smeerkahoven

Reputation: 173

Loading dynamic libraries using JNI and C++ with linux

Recently I'm learning JNI to execute C code. Of course I did basic examples that were on the web. Now Im trying to load a C library that makes dynamic library loading (dlopen). But Im fighthing with an error. Im posting my Java code, C ++ code and the error.

My Java Class

 /**
  *
  * @author glassfish
  */
 public class MediationJniWeb {

    public String library ;

    static {
       System.loadLibrary("-core-web");        
    }  

    /**
     *
     * @param library name of mediation core library [32]
     * @param method name of method to be executed [128]
     * @param parameters parameters of method [10240]
     *        [partype1,value1,...,valuen]...[partypen,value1,..,valuen]
     * @return
     */
     private native String execute();

     public static void main(String args[]) {
         //new MediationJniWeb().callToFunction(null, null, null) ;
         MediationJniWeb jniWeb = new MediationJniWeb();
         jniWeb.library = "libtest.so" ;

         System.out.println(jniWeb.execute());
     }
    }

I generate .class file with

javac MediationJniWeb

and I generate .h File with

javah -jni MediationJniWeb

my MediationJniWeb.h file is

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

#ifndef _Included_MediationJniWeb
#define _Included_MediationJniWeb
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     MediationJniWeb
 * Method:    execute
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_MediationJniWeb_execute
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

and my MediationJniWEb.cpp file

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
#include <dlfcn.h>
#include <iostream>

#include "MediationJniWeb.h"

using namespace std ;

typedef void (*test)(string);
/*
 * Class:     MediationJniWeb
 * Method:    execute
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_MediationJniWeb_execute
  (JNIEnv * env, jobject obj){

        const char * str_library ;
        jfieldID fid_library ;
        jstring jstr_library ;
        jboolean isCopy ;

        jclass cls = env->GetObjectClass( obj) ; 
        fid_library  = env->GetFieldID( cls,"library", "Ljava/lang/String;");
        jstr_library = ( jstring )env->GetObjectField( obj,fid_library);
        str_library = env->GetStringUTFChars( jstr_library, &isCopy) ; 

        void* handle = dlopen(str_library, RTLD_NOW); // open libtest.so

        if ( 0 == handle ) {
        cout << "failed to load 'libtest.so'. " << dlerror () <<endl;
        exit(1);
        }

        test t = (test)dlsym(handle, "_Z8testfuncSs"); // run default method
        if ( 0 == t ) {
        cout << "failed to load 'testfunc()'." << endl;
        exit(1);
        }
        t("Hello, World!");
        dlclose(handle); 

        /*
        */
        return env->NewStringUTF( str_library); // I just return library name just for fun
    }

  }

I compile with

g++ -shared -fpic -I//include/ -I//include/linux/ MediationJniWeb.cpp -o lib-core-web.so MediationJniWeb.cpp -ldl

this generate lib-core-web.so file. Then I copy this to $HOME/lib and I configure

LD_LIBRARY_PATH=$HOME/lib

Now I create my library libtest.so that is going to be executed by lib-core-web.so

I create file for shared libray mylib.cpp

#include <iostream>
#include <string>

using namespace std;

void testfunc(string s)
{
  cout << s << endl;
}

I compile this that is going to work as a shared library with

g++ -shared -fpic -o libtest.so mylib.cpp

This command generates libtest.so file.. and also, I copy it to $HOME/lib

That's all I do to call from JNI to a C++ library to load a dynamic library. when I execute MediationJniWeb java class I'm having this error

failed to load. libtest.so: cannot open shared object file: No such file or directory

What do I have to do with libtest.so ?? where do I have to put it ?

I have on mind that configuring only LD_LIBRARY_PATH variable with right path, JVM should know where to find all needed libraries to be loaded.

Please help with your comments and let me know where my mistakes are.

Thanks in advance !

Upvotes: 0

Views: 2069

Answers (1)

smeerkahoven
smeerkahoven

Reputation: 173

A simple thing I have done

instead of

jniWeb.library = "libtest.so"

library parameter to be loaded I declared

jniWeb.library = "/home/myuser/lib/libtest.so"

And it worked !

Upvotes: 1

Related Questions