My JNI was working fine as far as i remember a couple of days. Now i am getting the error:
DODJNI.h:15: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘void’
However this is the machine created header file and so presumly there should be no errors with the header file, as it says at the top to not modify it
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class DoDJNI */
#ifndef _Included_DoDJNI
#define _Included_DoDJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: DoDJNI
* Method: parseCommand
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_DoDJNI_parseCommand
(JNIEnv *, jobject, jstring);
#ifdef __cplusplus
}
#endif
#endif
Related
I can't get the JNI sample by Netbeans to work.
gcc -shared -m32 -c -g -I../../../../../Program\ Files/Java/jdk1.8.0_131/include -I../../../../../Program\ Files/Java/jdk1.8.0_131/include/win32 -MMD -MP -MF "build/Debug/Cygwin-Windows/JNIDemo.o.d" -o build/Debug/Cygwin-Windows/JNIDemo.o JNIDemo.c
In file included from /cygdrive/c/Program Files/Java/jdk1.8.0_131/include/jni.h:45:0,
from JNIDemoJava.h:6,
from JNIDemo.c:2:
/cygdrive/c/Program Files/Java/jdk1.8.0_131/include/win32/jni_md.h:34:9: error: unknown type name '__int64'
typedef __int64 jlong;
^
#ifndef _Included_jnidemojava_Main
#define _Included_jnidemojava_Main
#include <jni.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: jnidemojava_Main
* Method: nativePrint
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_jnidemojava_Main_nativePrint
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#ifndef __int64
#define __int64 signed_64_bit_type long long
#endif
#endif
I am trying to link a Java swing frontend to the c++ backend using JNI. I am able to generate a class file and header file for that class. I could also write the .cpp file and also generate a library file. But when I try to run my application I get an error undefined symbol: __gxx_personality_v0.
I went through many examples on stackoverflow but none of it worked in my case. I made sure I have libgcc, libgcj and libstd++. Also added pragma GCC java_exceptions on the top of the JNI header file.
But none of these worked.
Java file - InitJNI.java
public class InitJNI {
public native String callMethod(String str);
public static void init(String s){
System.out.println("-------inside InitJNI.java--------");
System.loadLibrary("eg1");
System.out.println("Library loaded in InitJNI--------");
InitJNI init1 = new InitJNI();
init1.callMethod(s);
}
}
JNI header file - InitJNI.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class org_openscience_jchempaint_application_InitJNI */
#ifndef _Included_InitJNI
#define _Included_InitJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: InitJNI
* Method: callMethod
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_InitJNI_callMethod
(JNIEnv *, jobject, jstring);
#ifdef __cplusplus
}
#endif
#endif
Cpp file - InitJNI.cpp
#include "InitJNI.h"
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#pragma GCC java_exceptions
JNIEXPORT jstring JNICALL Java_InitJNI_callMethod
(JNIEnv * env, jobject, jstring string){
char buf[128];
const char *str = env->GetStringUTFChars(string, NULL);
printf("%s", str);
env->ReleaseStringUTFChars(string, str);
}
I am trying to create a shared lib using command:
g++ -shared -fpic -o libeg1.so -I/usr/java/include -I/usr/java/include/linux InitJNI.cpp
Which generates libeg1.so file. But my application does not run. It gives me
undefined symbol: __gxx_personality_v0
Any help with this is appreciated.
Thank you!
I know this is an often-seen problem and after search on the web, problem still not solved. -Djava.library.path is already added to the command.
Here is my java file
public class TestJni
{
public native void print(A a);
static{
System.loadLibrary("MyJni");
}
public static void main(String []args){
new TestJni().print(new A());
}
}
class A{
void show(){
System.out.println("In a show function");
}
}
I am trying to create an instance 'a' which is A class.
Pass it to native method print and let native method to invoke show() method.
Compile .java into .class
javac TestJni.java
Now I have three files: A.class TestJni.class TestJni.java
Use
javah -classpath . TestJni
to get .h file which is like:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class TestJni */
#ifndef _Included_TestJni
#define _Included_TestJni
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: TestJni
* Method: print
* Signature: (LA;)V
*/
JNIEXPORT void JNICALL Java_TestJni_print
(JNIEnv *, jobject, jobject);
#ifdef __cplusplus
}
#endif
#endif
Rename it to MyJni.h by
mv TestJni.h MyJni.h
Create MyJni.c by
vim MyJni.c
the content of MyJni.c is:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
#include "MyJni.h"
/* Header for class TestJni */
#ifndef _Included_TestJni
#define _Included_TestJni
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: TestJni
* Method: print
* Signature: (LA;)V
*/
JNIEXPORT void JNICALL Java_TestJni_print
(JNIEnv *env, jobject obj, jobject o){
jclass cls = (*env)->GetObjectClass(env, o);
jmethodID mid = (*env)->GetMethodID(env, cls, "show", "()V");
(*env)->CallVoidMethod(env, o, mid);
}
#ifdef __cplusplus
}
#endif
#endif
Build .so file by
gcc -fPIC -shared -o libMyJni.so MyJni.c -I. -I$JAVA_HOME/include -I$JAVA_HOME/include/linux
And now I have 5 files [A.class libMyJni.so MyJni.c MyJni.h TestJni.class TestJni.java] in my directory: /home/grid/code/tmp
Run java program:
java -cp . -Djava.library.path=. TestJni
Now I get the Error which is
Exception in thread "main" java.lang.UnsatisfiedLinkError: TestJni.print(LA;)V
at TestJni.print(Native Method)
at TestJni.main(TestJni.java:10)
I am coding under Ubuntu 14.10 and gcc program is the default one.
I really not able to figure out what is wrong.
Please help me to correct the program.
Thank you very much in advance!!!
Remove the
#ifndef _Included_TestJni
#define _Included_TestJni
...
#endif
from the source file. You've already #defined the include guard in the header, so this effectively comments out the code.
Remove the #include "MyJni.h" or
#ifndef _Included_TestJni
#define _Included_TestJni
//..
#endif
Exception in thread "main" java.lang.UnsatisfiedLinkError: TestJni.print(LA;)V this usually happen when JNI can't find the symbol definition in your library. You can use nm to analyze the JNI function you call to see if it is defined and exported in your library.
$ nm libMyJni.so
00000000000005ac T Java_TestJni_print
0000000000200e40 a _DYNAMIC
0000000000200fe8 a _GLOBAL_OFFSET_TABLE_
w _Jv_RegisterClasses
0000000000200e20 d __CTOR_END__
0000000000200e18 d __CTOR_LIST__
You can try using System.load. iirc System.loadLibrary loads .so/.dll files from the default location. System.load should work with an absolute path to the .so/.dll file.
I had a previously working JNI lib,
for some reason (I am not aware of any curcial changes) I can't use it anymore, as I get the following error:
Exception in thread "main" java.lang.UnsatisfiedLinkError: de.ifi.lmu.sommerd.ftsserver.jni.IndexJNI.loadIndex(Ljava/lang/String;)V
at de.ifi.lmu.sommerd.ftsserver.jni.IndexJNI.loadIndex(Native Method)
So here is my test setup:
package de.ifi.lmu.sommerd.ftsserver.jni;
public class IndexJNI {
static {
System.load("/home/XXX/workspace/IndexJNI/resources/newLib.so");
System.out.println("Loading library worked");
IndexJNI.loadIndex("");
}
public static native void loadIndex(String indexName);
}
And here the relevant parts of the .h and .c files:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class de_ifi_lmu_sommerd_ftsserver_jni_IndexJNI */
#ifndef _Included_de_ifi_lmu_sommerd_ftsserver_jni_IndexJNI
#define _Included_de_ifi_lmu_sommerd_ftsserver_jni_IndexJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: de_ifi_lmu_sommerd_ftsserver_jni_IndexJNI
* Method: loadIndex
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_de_ifi_lmu_sommerd_ftsserver_jni_IndexJNI_loadIndex
(JNIEnv *, jobject, jstring);
#ifdef __cplusplus
}
#endif
#endif
The .c file
JNIEXPORT void JNICALL Java_de_ifi_lmu_sommerd_ftsserver_jni_IndexJNI_loadIndex
(JNIEnv * env, jclass jc, jstring indexName) {
...
}
And this is my makefile:
test_gcc_lib: run_queries.o
g++ -shared -fPIC run_queries.o SSA.a -o newLib.so
So the problem was that I had changed the call to static,
so now the signature was not correct anymore.
I just had to change jobject to jclass.
AFTER EDIT
I get the this error
1> Creating library D:\Jni tester\Debug\Jni tester.lib and object D:\Jni tester\Debug\Jni tester.exp
1>MSVCRTD.lib(crtexe.obj) : error LNK2019: unresolved external symbol _main referenced in function ___tmainCRTStartup
1>D:\Jni tester\Debug\Jni tester.exe : fatal error LNK1120: 1 unresolved externals
when i run the following code :
#include <jni.h>
#include <stdio.h>
#include "HelloWorld.h"
JNIEXPORT void JNICALL
Java_HelloWorld_print( JNIEnv *env , jobject obj) {
printf("Hello World!\n");
return;
}
This is the header file HelloWorld.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloWorld */
#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloWorld
* Method: print
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloWorld_print
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
Why do i get this error ?
JNIENv should be JNIEnv (lower case n) as shown by this Getting Started guide.
Edit: As seems from your error, you should define the project as a DLL, in your case it looks for the main method since it tries to create an executable.