zobayer1
June 19th, 2013, 08:24 AM
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]
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]
/* 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]
#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]
#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]
#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]
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 :)
The java file [HelloJNI.java]
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]
/* 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]
#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]
#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]
#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]
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 :)