Results 1 to 9 of 9

Thread: JNI with C++ : UnsatisfiedLinkError

  1. #1
    Join Date
    Mar 2010
    Location
    Dhaka, Bangladesh
    Beans
    210
    Distro
    Ubuntu 12.04 Precise Pangolin

    JNI with C++ : UnsatisfiedLinkError

    It was working when I wrote the Hello World version of it, i.e. with a void function, but when I add return types, it continuously gives UnsatisfiedLinkError exception. Here is what I am trying:

    The java file [HelloJNI.java]
    Code:
    import java.io.*;
    import java.util.*;
    
    public class HelloJNI {
        static {
            try {
                System.loadLibrary("hello");
            } catch(UnsatisfiedLinkError e) {
                System.out.println(e);
                System.exit(1);
            }
        }
    
        public static native boolean sayHello(String name);
    
        public static void main(String[] args) {
            BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
            String name;
            boolean ret;
            try {
                while((name = stdin.readLine()) != null) {
                    if(name.equals("EXIT")) {
                        break;
                    }
                    ret = sayHello(name);
                    System.out.println(ret);
                }
            } catch(IOException e) {
                System.out.println(e);
            }
        }
    }
    javah generated the following file: [HelloJNI.h]
    Code:
    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class HelloJNI */
    
    #ifndef _Included_HelloJNI
    #define _Included_HelloJNI
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     HelloJNI
     * Method:    sayHello
     * Signature: (Ljava/lang/String;)Z
     */
    JNIEXPORT jboolean JNICALL Java_HelloJNI_sayHello
      (JNIEnv *, jclass, jstring);
    
    #ifdef __cplusplus
    }
    #endif
    #endif
    Here is the actual logic of the C++ program:
    [HelloJNILogic.h]
    Code:
    #ifndef _HELLO_JNI_LOGIC_H
    #define _HELLO_JNI_LOGIC_H
    
    #ifdef __cplusplus
        extern "C" {
    #endif
    
        bool sayHello(const char* name);
    
    
    #ifdef __cplusplus
        }
    #endif
    
    #endif
    [HelloJNILogic.cpp]
    Code:
    #include "HelloJNILogic.h"
    
    #include <cstring>
    
    bool sayHello(const char* name) {
        int len = strlen(name);
        return len % 2 == 0;
    }
    And finally here is the C file for interfacing C++ and JNI together: [HelloJNIInterface.c]
    Code:
    #include <jni.h>
    
    #include "HelloJNI.h"
    #include "HelloJNILogic.h"
    
    JNIEXPORT jboolean JNICALL Java_HelloJNI_sayHello(JNIEnv *env, jobject obj, jstring name) {
        const char *str = env->GetStringUTFChars(name, 0);
        bool ret = sayHello(str);
        env->ReleaseStringUTFChars(name, str);
        if(ret) return JNI_TRUE;
        return JNI_FALSE;
    }
    Finally this is the commands I am using to compile and execute the program, I have put them in a sh file for the ease of work [test.sh]
    Code:
    javac HelloJNI.java
    javah HelloJNI
    g++ -I"$JAVA_HOME"/include -I"$JAVA_HOME"/include/linux -shared -fpic -o libhello.so HelloJNIInterface.c HelloJNILogic.cpp
    java -Djava.library.path=. HelloJNI
    When I execute program, it starts and waits for my input and when input is supplied, it shows the UnsatisfiedLinkError exception. How to find the bug? Thanks in advance

  2. #2
    Join Date
    Mar 2010
    Location
    Dhaka, Bangladesh
    Beans
    210
    Distro
    Ubuntu 12.04 Precise Pangolin

    Re: JNI with C++ : UnsatisfiedLinkError

    After trying a bit I figured out the problem.
    Here the signature is something like:
    Code:
    JNIEXPORT jboolean JNICALL Java_HelloJNI_sayHello   (JNIEnv *, jclass, jstring);

    However, the tutorial I was following had jobject instead of parameter jclass, so after changing this in the above code [HelloJNIInterface.c], the problem is solved.

    Is it possible to do this with .a files instead of .so files?

  3. #3
    Join Date
    Aug 2010
    Location
    Lancs, United Kingdom
    Beans
    1,312
    Distro
    Ubuntu Mate 16.04 Xenial Xerus

    Re: JNI with C++ : UnsatisfiedLinkError

    Quote Originally Posted by zobayer1 View Post
    Is it possible to do this with .a files instead of .so files?
    Not currently. See http://openjdk.java.net/jeps/178

  4. #4
    Join Date
    Mar 2010
    Location
    Dhaka, Bangladesh
    Beans
    210
    Distro
    Ubuntu 12.04 Precise Pangolin

    Re: JNI with C++ : UnsatisfiedLinkError

    Quote Originally Posted by spjackson View Post
    Thanks man, just one more question, if I just change the .so file, should the entire jni class needs to be recompiled? or if the class is recompiled, do I need to compile the .so file again?

  5. #5
    Join Date
    Jun 2007
    Location
    Maryland, US
    Beans
    6,274
    Distro
    Kubuntu

    Re: JNI with C++ : UnsatisfiedLinkError

    Quote Originally Posted by zobayer1 View Post
    Thanks man, just one more question, if I just change the .so file, should the entire jni class needs to be recompiled? or if the class is recompiled, do I need to compile the .so file again?
    Describe what you mean by "changing" the library? Whereas you may change the implementation within functions, you may not change the signature of existing functions that are called upon by your JNI layer. If you perform the latter, then obviously you will need to remake your entire project.

    Btw, the JNI layer does not need to be in a C file; you should consider placing it within a C++ file. For more complex projects, you may it useful to employ the use of C++ constructs in the JNI layer.

  6. #6
    Join Date
    Mar 2010
    Location
    Dhaka, Bangladesh
    Beans
    210
    Distro
    Ubuntu 12.04 Precise Pangolin

    Re: JNI with C++ : UnsatisfiedLinkError

    Quote Originally Posted by dwhitney67 View Post
    Describe what you mean by "changing" the library? Whereas you may change the implementation within functions, you may not change the signature of existing functions that are called upon by your JNI layer. If you perform the latter, then obviously you will need to remake your entire project.

    Btw, the JNI layer does not need to be in a C file; you should consider placing it within a C++ file. For more complex projects, you may it useful to employ the use of C++ constructs in the JNI layer.
    Yeah later I have changed that to a cpp file. And (hopefully) only the algorithm in body will change, but the signature of the function will not change. So, I only need to re-compile the part which is changed and not the whole project if I modify the body of the function but not the signature.

  7. #7
    Join Date
    Jun 2007
    Location
    Maryland, US
    Beans
    6,274
    Distro
    Kubuntu

    Re: JNI with C++ : UnsatisfiedLinkError

    Quote Originally Posted by zobayer1 View Post
    So, I only need to re-compile the part which is changed and not the whole project if I modify the body of the function but not the signature.
    That's correct. Try an experiment... insert a call to std::cout in your C++ library; then rebuild the library.

    Then, merely execute your Java program (there's no need to recompile it). You should see the statement outputted by the cout.

  8. #8
    Join Date
    Jun 2011
    Location
    Paris
    Beans
    55

    Re: JNI with C++ : UnsatisfiedLinkError

    OP, if you're feeling particularly daring, you might try bridj. It's a way to call native libraries like JNA, but it is compatible with C++. The difference between it and JNI is that you write java code for the bindings instead of the C/C++ bindings you write with JNI.

  9. #9
    Join Date
    Mar 2010
    Location
    Dhaka, Bangladesh
    Beans
    210
    Distro
    Ubuntu 12.04 Precise Pangolin

    Re: JNI with C++ : UnsatisfiedLinkError

    Quote Originally Posted by Leuchten View Post
    OP, if you're feeling particularly daring, you might try bridj. It's a way to call native libraries like JNA, but it is compatible with C++. The difference between it and JNI is that you write java code for the bindings instead of the C/C++ bindings you write with JNI.
    Well, surely I will give that a try, but in this project, I have to use JNI as other modules are build up using the similar fashion. Thanks for letting me know about that

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •