Hot questions for Using Ubuntu in java native interface

Top Java Programmings / Ubuntu / java native interface

Question:

Since a couple of weeks the SWI-Prolog Java interface crashes immediately in JNI_CreateJavaVM. Well, on most machines. It runs fine on one of my machines, which runs the same version of Ubuntu and openjdk ... I stripped this down to this little program:

#include <jni.h>
#include <stdio.h>
#include <stdlib.h>

static JavaVM *jvm;

int
main(int argc, char **argv)
{ JavaVMInitArgs vm_args = {0};
  JNIEnv *env;
  JavaVMOption opt[8] = {0};
  int optn = 0;
  int r;

  opt[optn++].optionString = "-Djava.class.path=" "jpl.jar:.";
  opt[optn++].optionString = "-Xrs";

  vm_args.version  = JNI_VERSION_1_2;
  vm_args.nOptions = optn;
  vm_args.options  = opt;

  r = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
  fprintf(stderr, "Got %d\n", r);
  exit(0);
}

That is compiled using

JVM=/usr/lib/jvm/java-8-oracle
#JVM=/usr/lib/jvm/java-1.8.0-openjdk-amd64

gcc -I$JVM/include \
    -I$JVM/include/linux \
    -L$JVM/jre/lib/amd64/server \
    -L$JVM/jre/lib/amd64 \
    -g -Wall -o t t.c -ljsig -ljava -lverify -ljvm

Gdb gives no usable stack trace as it claims a stack corruption somewhere in the JVM. I'm pretty lost as this crashes both using Oracle and OpenJDK java one assumes it is my fault. On the other hand, this worked for years and is what you find in all examples as well.

Platform is Ubuntu 16.04, amd64, gcc 5.4.0

valgrind says this. Funny enough, it says the same on the machine where it runs without crashing.

==9642== Memcheck, a memory error detector
==9642== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==9642== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==9642== Command: ./t
==9642== 
==9642== Warning: set address range perms: large range [0x5cb200000, 0x7c0000000) (noaccess)
==9642== Warning: set address range perms: large range [0x5cb200000, 0x5e0100000) (defined)
==9642== Warning: set address range perms: large range [0x7c0000000, 0x800000000) (noaccess)
==9642== Invalid write of size 4
==9642==    at 0x84C0BE7: ???
==9642==    by 0x84AE4E6: ???
==9642==    by 0x549C11A: ??? (in /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server/libjvm.so)
==9642==    by 0x545ABA6: ??? (in /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server/libjvm.so)
==9642==    by 0x545AFA1: ??? (in /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server/libjvm.so)
==9642==    by 0x545B3FF: ??? (in /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server/libjvm.so)
==9642==    by 0x545B1B1: ??? (in /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server/libjvm.so)
==9642==    by 0x545B3FF: ??? (in /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server/libjvm.so)
==9642==    by 0x584A9BB: ??? (in /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server/libjvm.so)
==9642==    by 0x54C31E1: JNI_CreateJavaVM (in /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server/libjvm.so)
==9642==    by 0x4007C7: main (t.c:22)
==9642==  Address 0xffeffea00 is on thread 1's stack
==9642==  4096 bytes below stack pointer

Answer:

I suspect this problem is related to the following kernel issue https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1699772

I am noticing what I think is the same issue in CentOS 7 after updating to latest packages:

  • java-1.8.0-openjdk-1.8.0.131-3.b12.el7_3.x86_64
  • Linux 3.10.0-514-21.2.el7.x86_64

If I reboot with Linux 3.10.0-514-21.1 the problem goes away.

Question:

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!!!


Answer:

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.

Question:

When I tried to compile Bazel 0.1.0 with protoc 3.0.0 alpha 3 and jdk 1.8 on Jetson TK1, I met this JNI link error in Building Bazel tools. INFO: Blaze version info: Build label: head (@125b349) Build target: bazel-out/local_linux-fastbuild/bin/src/main/java/bazel-main_deploy.jar Build time: Fri Feb 24 08:29:59 2017 (1487924999) Build timestamp: 1487924999 Build timestamp as int: 1487924999 Feb 24, 2017 9:08:10 AM com.google.devtools.build.lib.runtime.BlazeRuntime main INFO: Starting Blaze server with args [--max_idle_secs, 10800, --install_base=/home/ubuntu/.cache/bazel/_bazel_ubuntu/install/2dac0f619e9cc270a8fcbda27d4228ba, --install_md5=2dac0f619e9cc270a8fcbda27d4228ba, --output_base=/home/ubuntu/.cache/bazel/_bazel_ubuntu/9a43f1fcce27c7feee2a9f965aa85b05, --workspace_directory=/home/ubuntu/Downloads/bazel, --nofatal_event_bus_exceptions, --option_sources=blazerc:] JNI initialization failed: /home/ubuntu/.cache/bazel/_bazel_ubuntu/install/2dac0f619e9cc270a8fcbda27d4228ba/_embedded_binaries/libunix.so: /home/ubuntu/.cache/bazel/_bazel_ubuntu/install/2dac0f619e9cc270a8fcbda27d4228ba/_embedded_binaries/libunix.so: unexpected reloc type 0x03. Possibly your installation has been corrupted; if this problem persists, try 'rm -fr /home/ubuntu/.cache/bazel/_bazel_ubuntu/install/2dac0f619e9cc270a8fcbda27d4228ba'. java.lang.UnsatisfiedLinkError: /home/ubuntu/.cache/bazel/_bazel_ubuntu/install/2dac0f619e9cc270a8fcbda27d4228ba/_embedded_binaries/libunix.so: /home/ubuntu/.cache/bazel/_bazel_ubuntu/install/2dac0f619e9cc270a8fcbda27d4228ba/_embedded_binaries/libunix.so: unexpected reloc type 0x03 at java.lang.ClassLoader$NativeLibrary.load(Native Method) at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1941) at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1857) at java.lang.Runtime.loadLibrary0(Runtime.java:870) at java.lang.System.loadLibrary(System.java:1122) at com.google.devtools.build.lib.UnixJniLoader.loadJni(UnixJniLoader.java:25) at com.google.devtools.build.lib.unix.ProcessUtils.(ProcessUtils.java:27) at com.google.devtools.build.lib.util.ProcessUtils$1.getpid(ProcessUtils.java:53) at com.google.devtools.build.lib.util.ProcessUtils.getpid(ProcessUtils.java:77) at com.google.devtools.build.lib.util.OsUtils.forceJNI(OsUtils.java:56) at com.google.devtools.build.lib.util.OsUtils.maybeForceJNI(OsUtils.java:43) at com.google.devtools.build.lib.runtime.BlazeRuntime.newRuntime(BlazeRuntime.java:1437) at com.google.devtools.build.lib.runtime.BlazeRuntime.createBlazeRPCServer(BlazeRuntime.java:1328) at com.google.devtools.build.lib.runtime.BlazeRuntime.serverMain(BlazeRuntime.java:1301) at com.google.devtools.build.lib.runtime.BlazeRuntime.main(BlazeRuntime.java:1097) at com.google.devtools.build.lib.bazel.BazelMain.main(BazelMain.java:56) Feb 24, 2017 9:08:10 AM com.google.devtools.build.lib.runtime.BugReport printThrowableTo SEVERE: Blaze crashed java.lang.UnsatisfiedLinkError: /home/ubuntu/.cache/bazel/_bazel_ubuntu/install/2dac0f619e9cc270a8fcbda27d4228ba/_embedded_binaries/libunix.so: /home/ubuntu/.cache/bazel/_bazel_ubuntu/install/2dac0f619e9cc270a8fcbda27d4228ba/_embedded_binaries/libunix.so: unexpected reloc type 0x03 at java.lang.ClassLoader$NativeLibrary.load(Native Method) at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1941) at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1857) at java.lang.Runtime.loadLibrary0(Runtime.java:870) at java.lang.System.loadLibrary(System.java:1122) at com.google.devtools.build.lib.UnixJniLoader.loadJni(UnixJniLoader.java:25) at com.google.devtools.build.lib.unix.ProcessUtils.(ProcessUtils.java:27) at com.google.devtools.build.lib.util.ProcessUtils$1.getpid(ProcessUtils.java:53) at com.google.devtools.build.lib.util.ProcessUtils.getpid(ProcessUtils.java:77) at com.google.devtools.build.lib.util.OsUtils.forceJNI(OsUtils.java:56) at com.google.devtools.build.lib.util.OsUtils.maybeForceJNI(OsUtils.java:43) at com.google.devtools.build.lib.runtime.BlazeRuntime.newRuntime(BlazeRuntime.java:1437) at com.google.devtools.build.lib.runtime.BlazeRuntime.createBlazeRPCServer(BlazeRuntime.java:1328) at com.google.devtools.build.lib.runtime.BlazeRuntime.serverMain(BlazeRuntime.java:1301) at com.google.devtools.build.lib.runtime.BlazeRuntime.main(BlazeRuntime.java:1097) at com.google.devtools.build.lib.bazel.BazelMain.main(BazelMain.java:56)


Answer:

Bazel 0.1.0 is an old release, the latest is 0.4.4.

Did you try following the Compiling from Source instructions?