让 JNA 在 Java 1.4 下工作

Getting JNA to work under Java 1.4

由于与这个问题无关的原因,我坚持使用带有 Java 1.4 (java version "1.4.2" gij (GNU libgcj) version 4.1.2 20080704 (Red Hat 4.1.2-44)) 的旧 RHEL/CentOS 5 系统。根据 JNA 文档,它应该可以工作。然而,所提供的示例一开始并不顺利,因为它使用了 Java 1.5 的功能,即 varargs (void printf(String format, Object... args))。所以我想我会尝试使用更简单的 C 库调用,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
    }
}

所以我在本地部署 jna-master.zip 并连接它:

$ 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

编译正常:

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

但不会 运行:

$ 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)

javac -cp $CLASS_PATH ... 编译没有区别。

我在32位系统和64位系统(都是RHEL 5.3)上都试过了,错误都是一样的。

我做错了什么?

1.) 我检查了官方 JNA 库 类,结果如下:

  • JNA 4.0.0 -> 用 1.6 编译
  • JNA 3.5.0 -> 使用 1.4
  • 编译
  • JNA 3.5.2 -> 用 1.4 编译

当你准确地寻找它时,你也会找到它: 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.) 关于奇异的 java 版本你可以阅读 here。一些引述给你一些想法:

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

在 sun/oracle/open jdk 中,正确地进入 运行 JNA 有时已经足够棘手了 - 所以这不是一项简单的任务...