JNI_CreateJavaVM()每次运行我的应用程序时都会失败(确切地说)

时间:2012-05-04 06:11:13

标签: java c++ visual-studio visual-studio-2010 java-native-interface

我有一个Windows MFC应用程序:

(1)加载JVM(JNI_CreateJavaVM()

(2)将主线程附加到JVM(AttachCurrentThread()

(3)加载一些Java类和方法(FindClass()GetMethodID() / GetStaticMethodID()

(4)注册一些本机回调以供Java代码(RegisterNatives()

使用

(5)从JVM(DetachCurrentThread()

中分离线程

(6)销毁JVM(DestroyJavaVM()

以上所有功能每隔一段时间成功我运行应用程序。我知道他们成功了,因为除了上面的内容,我还与应用程序交互并成功调用Java静态方法,这些Java方法成功调用了我的本机回调。我的应用程序优雅地退出,并且可以确定已经执行了预期的Java函数和本机回调。

但是,每隔一次我运行应用程序,对JNI_CreateJavaVM()的调用失败(不填充JavaVM *)。 应用程序运行之间绝对没有任何变化。我只是运行一次(成功,甚至没有做除了上述6个步骤之外的任何事情),优雅地退出,再次运行,它来回失败。前后成功/失败没有例外 - 我可以运行数十次,并且它在成功之间每隔一段时间就会振荡,并且在JNI_CreateJavaVM()线上失败。

如有必要,我会粘贴更多代码。但是,我希望有人能够了解我所提供的内容。 (注意:这是一个BCGSoft MFC属性表应用程序,但我强烈怀疑这很重要。)

1 个答案:

答案 0 :(得分:4)

看起来你遇到了this bug(重述here),这可能永远不会被解决。

尽管它的名字,DestroyJavaVM()实际上并没有破坏JVM。它的作用是向JVM发出它应该关闭的信号,但是JVM实际上等待直到主线程以外的所有线程在实际关闭之前停止。实际上,即使这样,它也不会完全清理,因为the documentation表示(非常cryptically):“但JDK / JRE仍然不支持VM卸载。”

另外,我关注你的第2步,“将主线程附加到JVM”。您不需要将创建JVM的线程附加到JVM,也可以不分离该线程。如果你真的这样做,那么可能就是弄乱你的系统。 (创建JVM的线程是JVM的“主”线程。如果需要访问它,您只需要将其他本机线程附加/分离到JVM。)

顺便说一句,JNI_CreateJavaVM()成功时返回0,你说它在“失败”时间返回0,那么它在什么意义上失败了?您使用的是哪个JVM(版本,供应商)?