javacjnarhel5

Getting JNA to work under Java 1.4


For reasons not germane to this question, I'm stuck with an old RHEL/CentOS 5 system with Java 1.4 (java version "1.4.2" gij (GNU libgcj) version 4.1.2 20080704 (Red Hat 4.1.2-44)). According to the JNA documentation, it's supposed to work. However the example provided is off to a rocky start since it uses a feature of Java 1.5, namely varargs (void printf(String format, Object... args)). So I figured I'd try with a simpler C library call, strerror.

package ca...cl_client;

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;
import com.sun.jna.Pointer;

public class MainJNA {
    public interface CLibrary extends Library {
        CLibrary INSTANCE = (CLibrary)
            Native.loadLibrary((Platform.isWindows() ? "msvcrt" : "c"),
                CLibrary.class);
        Pointer strerror(int errno);
    }

    public static void main(String[] args) {
        System.out.println("Hello, World");

        System.out.println("err 22 : " + CLibrary.INSTANCE.strerror(22).getString(0)); //EINVAL
    }
}

So I deploy jna-master.zip locally and hook it up:

$ sudo -- ln -s /home/user/Downloads/Java/jna-master/dist/jna.jar /usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre/lib/jna.jar
$ export CLASS_PATH=.:/home/user/Downloads/Java/jna-master/dist/jna.jar

This compiles fine:

$ cd ~/Java
$ javac ./ca/gc/drdc_rddc/linux/utilinux/cl_client/MainJNA.java

But it won't run:

$ java -cp $CLASS_PATH ca...cl_client.MainJNA
Hello, World
Exception in thread "main" java.lang.ClassFormatError: com.sun.jna.Library (unrecognized class file version)
   at java.lang.VMClassLoader.defineClass(libgcj.so.7rh)
   at java.lang.ClassLoader.defineClass(libgcj.so.7rh)
   at java.security.SecureClassLoader.defineClass(libgcj.so.7rh)
   at java.net.URLClassLoader.findClass(libgcj.so.7rh)
   at java.lang.ClassLoader.loadClass(libgcj.so.7rh)
   at java.lang.ClassLoader.loadClass(libgcj.so.7rh)
   at java.lang.VMClassLoader.defineClass(libgcj.so.7rh)
   at java.lang.ClassLoader.defineClass(libgcj.so.7rh)
   at java.security.SecureClassLoader.defineClass(libgcj.so.7rh)
   at java.net.URLClassLoader.findClass(libgcj.so.7rh)
   at java.lang.ClassLoader.loadClass(libgcj.so.7rh)
   at java.lang.ClassLoader.loadClass(libgcj.so.7rh)
   at ca...cl_client.MainJNA.main(MainJNA.java:19)

Compiling with javac -cp $CLASS_PATH ... makes no difference.

I've tried this on both a 32-bit system and a 64-bit system (each RHEL 5.3), the error is the same.

What am I doing wrong?


Solution

  • 1.) I checked the official JNA library classes with the following result:

    And when looking exactly for that you'll find it, too: Switch to 1.6 (In the release notes for version 4.0). Additionally there is an issue #109. So your last working version would be 3.5.2.

    2.) Regarding the exotic java version you may read here. Some quotes to give you some ideas:

    "gij hasn't passed the Sun compatability test, and should be considered a separate platform for building, testing etc."

    "GCJ is not equivalent to Sun's JDK or JRE, so you may find that certain things you need aren't included in the API.

    "gij is very ancient, and while I don't have references I doubt it's reliable enough to support commercial applications."

    Getting to run JNA correctly is sometimes tricky enough in a sun/oracle/open jdk - so this won't be a trivial task...