【问题标题】:How to fix JNI project that does not run如何修复不运行的 JNI 项目
【发布时间】:2023-03-30 15:44:02
【问题描述】:

我有一个简单的 JNI 项目,它可以编译。但是当我运行它时,我收到以下错误:

$ java HelloJNI
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.ClassFormatError: Extra bytes at the end of class file HelloJNI
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(Unknown Source)
        at java.security.SecureClassLoader.defineClass(Unknown Source)
        at java.net.URLClassLoader.defineClass(Unknown Source)
        at java.net.URLClassLoader.access$100(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)

我不得不改变很多东西。在使用 gcc 的 Ubuntu 上;它有效:

ghostrider@:~/programing/java/jni/HelloJNI$ java -Djava.library.path=. HelloWorld
Hello from C!
ghostrider@:~/programing/java/jni/HelloJNI$ ls
ctest.c  HelloWorld.class  HelloWorld.h  HelloWorld.java  libctest.so

我用这个link 让它工作。

所以我现在的问题是我可以使用 gcc 编译 Windows 架构还是必须安装 MinGw 才能做到这一点? 感谢大家的帮助。

我刚刚验证了这适用于 MinGw-64

C:\Users\sansari\Downloads\x86_64-w64-mingw32-gcc-4.8.0-win64_rubenvb\mingw64\java>gcc -o ctest.dll -shared -I"%JAVA_HOME%\include" -I"%JAVA_HOME%\include\win32" ctest.c -m64

C:\Users\sansari\Downloads\x86_64-w64-mingw32-gcc-4.8.0-win64_rubenvb\mingw64\java>ls
HelloWorld.class  HelloWorld.h  HelloWorld.java  ctest.c  ctest.dll

C:\Users\sansari\Downloads\x86_64-w64-mingw32-gcc-4.8.0-win64_rubenvb\mingw64\java>java HelloWorld
Hello from C!

【问题讨论】:

  • javac 使用哪些选项? java 版本是否与您编译时的目标 VM 匹配?
  • 我只是使用了 javac HelloJNI.java,是的,VM 和 java 应该匹配。我在没有java的笔记本电脑上做这个。我刚刚安装了JDK并使用MinGw编译了c部分。
  • 到你的新问题。您可以使用任何能够生成 Windows 二进制文件的编译器。 MinGW 是port of the GNU Compiler Collection (GCC), including C, C++, ADA and Fortran compilers

标签: java c java-native-interface shared-libraries mingw


【解决方案1】:

我相信你做错了什么,因为类加载器抱怨一个损坏的类。

通常需要以下步骤(您没有告诉我们您做了哪一步)

javac HelloJNI.java
javah -jni HelloJNI
# compile your HelloJNI.cpp

修复 Java 类中的库名称

instead of  : System.loadLibrary("hello");
it should be: System.loadLibrary("HelloJNI");

以下步骤在 CentOS 7 上生成一个有效的 DLL(抱歉手头没有 MinGW for Windows)

javac HelloJNI.java
javah HelloJNI
x86_64-w64-mingw32-gcc -Wl,-kill-at -Wall -O0 -o HelloJNI.dll -shared \
   -I. -I/usr/lib/jvm/java-openjdk/include \
   -I/usr/lib/jvm/java-openjdk  /include/linux HelloJNI.cpp

HelloJNI.classHelloJNI.dll 复制到64 位Windows 机器上的同一目录中。

java HelloJNI

输出

Hello World!

【讨论】:

  • @Suboptimal- 好吧,我更改了库名称,然后再次编译。我想我需要一些有关 java 库路径的帮助。请注意帖子主要部分的输出。
  • 我想我可能已经找到了问题所在。我的机器是64位的机器,我安装的java版本也是64位的。当我使用 gcc 时,我是否应该指定我想要一个 64 位的 dll 文件?我使用 gcc 进行其他 c 编译,并且能够执行该程序。
  • @user3326293 JVM调用的共享库必须具有相同的架构。您不能混合使用 64 位和 32 位。所以你需要指定你想要一个 64 位的 DLL。
  • @SubOptimal- 你这个家伙!哥们,你帮了很多忙。将您的用户名更改为我想说的超人。
  • @user3326293 很高兴听到您的问题可以解决。
猜你喜欢
  • 2011-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-31
  • 1970-01-01
  • 2021-01-27
  • 2022-01-21
相关资源
最近更新 更多