我无法使用JNI这两个缺点。我想更多地了解他们:
难以调试运行时错误 本机代码
JNI代码中的错误会占用整个JVM,并且不提供任何正常恢复机制
答案 0 :(得分:26)
答案 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共享库没有更新,反之亦然),则可以在类加载时抛出异常。