使用Java Native Interface的缺点

时间:2009-09-08 13:09:06

标签: java java-native-interface

我无法使用JNI这两个缺点。我想更多地了解他们:

  • 难以调试运行时错误 本机代码

  • JNI代码中的错误会占用整个JVM,并且不提供任何正常恢复机制

6 个答案:

答案 0 :(得分:26)

难以调试

  • 您需要一个C / C ++调试器来调试本机代码。不可能轻易地从Java转向C / C ++代码。 (虽然可以同时调试它们。我已经用Eclipse和CDT插件完成了它,但这很痛苦)

JNI中的错误

  • 本机库中的错误C / C ++代码可能/将导致JVM无法恢复的核心转储/分段错误,因此整个应用程序崩溃。

答案 1 :(得分:13)

你将失去使用Java的优势之一,你的应用程序不再是平台独立的,还有很多其他问题:也许你会支持Windows的DLL和Linux的.so文件,每一个它们有自己的编译器,不同的调试工具,不同的依赖关系,可能有不同的错误,构建过程更复杂,需要测试更多代码等等。

答案 2 :(得分:2)

  

难以在本机代码中调试运行时错误

你见过Java中的堆栈跟踪吗?嗯,他们非常用户友好,他们告诉你大多数时间,行号,类方法和失败的。你没有Native代码。

  

JNI代码中的错误会占用整个JVM,并且不提供任何正常恢复机制

当你运行java代码时,所有代码都在JVM的控制下运行,如果出现问题,JVM可以处理它。您没有使用本机代码进行控制。

答案 3 :(得分:1)

虽然理论上不应该这样,但在实践中,我发现基于JNI的代码非常脆弱 - 我发现这是一个维护噩梦。小的更改甚至只是JVM升级都会导致模糊的问题。使用更新的Java版本可能会有所改进(我现在回到JDK 1.3或更早版本)。

答案 4 :(得分:1)

我不确定JNI,但是如果你使用JNA,你可以设置Native.setProtected(true)并且它会抛出错误而不是崩溃JVM,这样你就可以捕获它试试......抓住。所以第二个缺点不是问题。 (见source code

答案 5 :(得分:0)

我不确定这是否有帮助,但我使用本机方法在我的JNI / C代码中设置静态标志以打开或关闭调试跟踪(默认为关闭)。然后我在每个JNI函数的开头使用了旧的printf()调用,只有在设置了标志时才会执行。它很粗但很有用。

在Java类及其JNI函数之间提供某种版本检查也是一个好主意。这可以通过从静态类初始化程序块调用的JNI函数来完成。如果客户端具有错误的库组合(即,jar文件已更新但JNI共享库没有更新,反之亦然),则可以在类加载时抛出异常。