views:

207

answers:

1

I'm trying to create a simple Java app that uses JNI to call some native functions. I've followed the examples in the JNI Programming Guide and can't seem to get them to work. I have the following Hello World program, written in Java:

class HelloWorld {
    private native void print();

    public static void main(String [] args) {
        new HelloWorld().print();
    }

    static {
        System.load("/home/mike/Desktop/libHelloWorld.so");
    }
}

I compile it using javac HelloWorld.java, just like normal.

I also have the C implementation of the print function, in the HelloWorld.c file:

#include <jni.h>
#include <stdio.h>
#include "HelloWorld.h"

JNIEXPORT void JNICALL
Java_HelloWorld_print(JNIEnv *env, jobject obj) {
    printf("Hello world!\n");
    return;
}

Then I run javah -jni HelloWorld, and finally the following:

gcc34 -shared -fpic -o libHelloWorld.so -I/<path to JDK>/include -I/<path to JDK>/include/linux HelloWorld.c

gcc34 is the name of the GCC program on my machine here at work (I don't control that) and I obviously place the real path to the JDK in that command. When I run my program, using the standard java HelloWorld, I get an error saying the following:

Exception in thread "main" java.lang.UnsatisfiedLinkError: /home/mike/Desktop/libHelloWorld.so: /home/mike/Desktop/libHelloWorld.so: wrong ELF class: ELFCLASS64 (Possible causes: architecture word width mismatch)
    at java.lang.ClassLoader$NativeLibrary.load(Native Method)
    at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1778)
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1674)
    at java.lang.Runtime.load0(Runtime.java:770)
    at java.lang.System.load(System.java:1003)
    at HelloWorld.<clinit>(HelloWorld.java:8)
Could not find the main class: HelloWorld. Program will exit.

I know I'm running a 32-bit JVM (and unfortunately, as of right now, I'm not allowed to get a 64-bit JVM). I tried telling GCC to compile in 32-bit mode using the "-m32" option, but we don't have (and again, can't get) what we need for that. EDIT: I was able to move my files to a machine able to compile in 32-bit mode. So I did that, then verified that my libHelloWorld.so file was 32-bit by runnning file libHelloWorld.so and got ELF32-bit MSB dynamic lib SPARC Version 1, dynamically linked, not stripped, no debugging information available. I also ran java -version and got Java HotSpot(TM) Server VM (build <blah>, mixed mode) so it seems this JVM is running in 32-bit mode.

Why am I still getting this error?

+1  A: 

Yup :-). SO won't let me submit a one-word answer, so here are some possibly-useful Google hits.

Matt Solnit
Thanks for the quick answer. I already Googled it and just wanted to make sure... if we're right, it means my job's going to become a lot harder, haha. Thanks again!
Mike
I'm very curious why you're not able to somehow get access to a 32-bit compiler. Even if you don't have the actual hardware available, could you use a virtual machine (or a cloud like EC2)?
Matt Solnit
It's because of work politics. Awfully annoying.
Mike
You can submit a one-word answer if it is a long enough word. Welsh and German are useful for this - but prohibited on SO.
Jonathan Leffler
Seems the problem still exists... see above!
Mike
Nevermind! When I moved the files over to the new machine that could compile in 32-bit, I forgot to change the path that System.load is given. I did that now, and it works. Thanks again Matt.
Mike