1

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?

Urhixidur
  • 2,270
  • 2
  • 19
  • 24
  • `(GNU libgcj)` is not Oracle or Sun Java. It's part of gcc. – Elliott Frisch May 31 '17 at 20:44
  • @Elliott Frisch That may be, but it's what RHEL 5.3 comes with. I have to live with it. Are you saying it doesn't conform to the Java 1.4 standard, a bit like the old Microsoft JVM used to? – Urhixidur May 31 '17 at 20:50
  • Good luck. Even Java 1.7 is EOL, so I'd argue an upgrade is passed due. – Elliott Frisch May 31 '17 at 20:57
  • 3
    The exception is telling you that the class `com.sun.jna.Library` that Java is attempting to load from your JNA jar is written to a more recent classfile spec than any your Java implementation knows about. It was almost certainly compiled with a newer version of the Java compiler than v1.4. Your Java will never load it. Your alternatives are to get or build JNA for your version of Java (unsure whether this is possible) or to get a newer Java (this certainly *is*, or at least *was*, possible; try OpenJDK). – John Bollinger May 31 '17 at 21:10
  • @JohnBollinger Honestly, in my opinion, that's an acceptable answer right there – cbr Jun 01 '17 at 06:42

1 Answers1

3

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

  • JNA 4.0.0 -> compiled with 1.6
  • JNA 3.5.0 -> compiled with 1.4
  • JNA 3.5.2 -> compiled with 1.4

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

Community
  • 1
  • 1
Lonzak
  • 9,334
  • 5
  • 57
  • 88
  • I suspected as much. Why is JNA hiding it's compatibility level so well? This is the kind of thing that ought to be covered first in the README. Sheesh. – Urhixidur Jun 01 '17 at 12:51
  • @Urhixidur, I'd rate compatibility with Java 6 as *highly* compatible here in 2017. Oracle has not provided even *paid* support for Java 1.4 since 2013. For its part, Java 6 reached official end-of-life in 2013, though paid support may still be available for the time being. The gij / gcj dimension is altogether different; Oracle's apparent position that it is an unsupported variant that they therefore don't need to think about seems altogether reasonable to me. – John Bollinger Jun 01 '17 at 13:08
  • Yup, replacing JNA 4.4.0 with 3.5.2 did the trick. I can move on! – Urhixidur Jun 01 '17 at 14:10