我如何知道我的 Java 应用程序是否使用“本机代码”?
关于最近的问题,我收到评论询问我是否在我的应用程序中使用“本机代码”。现在,我知道有一些方法可以使用 一个叫做“JNI”的东西。我读过该维基百科条目,但我从未使用过它。
我正在使用许多库,其中一些可能会也可能不会使用本机代码。我如何知道他们是否这样做?我不需要安装任何 SO(在 Linux 上运行),但我想这并不意味着这些库没有使用任何 SO?我是否必须浏览所有文档(不同库的质量差异很大)或者我可以对 JAR 进行一些分析吗?
On a recent question, I got comments asking whether I was using "native code" in my application. Now, I know that there is some way to call code in traditional binary libraries (DLLs, SOs) from inside a Java application using a thing called "JNI". I have read that Wikipedia entry but I never used this.
I am using a number of libraries, some of which may or may not use native code. How do I find out if they do? I did not have to install any SOs (running on Linux), but I guess that doesn't mean the libraries are not using any? Do I have to browse through all the documentation (which varies greatly in quality between libraries) or can I do some analysis on the JARs?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
通常使用需要 JNI 的库需要一些额外的设置(例如将
.dll
或.so
文件放在正确的位置或设置java.library.path
系统属性)。如果您什么也没做,那么很可能您没有在任何地方使用 JNI。这也是有可能的,因为只有非常专业的库才需要 JNI。
但是还有 JNA,它是 JNI 的包装器,简化了它的用法,有时不需要进行任何显式设置。如果您的某个库使用了它,那么就很难检测到。
如果您收到故障转储,则检查是否有任何非标准库可以提示用户加载的本机库是否是罪魁祸首。
Usually using libraries that require JNI requires some additional setup (like putting
.dll
or.so
files in the right places or setting thejava.library.path
System property).If you did nothing of that, then chances are that you're not using JNI anywhere. This is also somewhat likely, as only quite specialized libraries require JNI.
However there's also JNA, which is a wrapper around JNI which simplifies its usage and which sometimes makes it unnecessary to do any explicit setup. If that's used by one of your libraries, then it's harder to detect.
If you get a crash dump, then checking that for any non-standard libraries can give a hint if a user-loaded native library is to blame.
挑剔的是,每个 Java 应用程序至少都间接使用 JNI。例如, System 类包含几个
native
方法,映射到本机 JRE(从其源代码中可以看出)。您的程序/库是否(直接或间接)使用标准 JRE 中包含的函数之外的其他本机函数,确实很难检测到。
.dll
s /.so
s 可以打包到.jar
中,仅在需要时提取,因此不必 安装本机库并不保证它不使用任何库。不过,通常应该在库文档中说明这一点,因为供应商可能不会为每个可以想象的运行 Java 的系统提供二进制文件。但可以肯定的是,我认为唯一的方法是扫描源代码以获取native
方法。To nitpick, every single Java application uses JNI indirectly at least. For example, System class contains several
native
methods, which map to the native JRE (as can be seen from its source code).Whether your program/libraries use (directly or indirectly) some other native functions than those contained in the standard JRE, is indeed hard to detect. The
.dll
s /.so
s may be packed into the.jar
, to be extracted only when needed, so not having to install native libraries doesn't guarantee that it doesn't use any. It should usually be stated in the library documentation, though, because the vendor probably won't provide binaries for every imaginable system that Java runs on. But to be sure, I think the only way is to scan through the source code fornative
methods.如果 java 库 (jar) 使用本机库(Windows 上的 dll 或 Linux 上的 so),那么它很可能是系统范围内众所周知的库(例如Linux 上的 glibc)或自定义的。在最后一种情况下,通常将其打包在 jar 中,因此您只需使用 ZIP 解压程序(即 Windows 上的 7zip 即可)将其打开并浏览文件。如果面向 Windows,您应该看到 dll 文件,如果面向 Unix 平台,您应该看到 so 文件,甚至两者都有。本机库文件通常保留在 jar 的根级别。
如果 jar 使用自定义库,但它与应用程序一起打包,通常会将本机库与其他应用程序文件一起保留在外部文件夹中(在这种情况下,没有达成共识)。在这种情况下,您应该查找应用程序启动器(bat / sh 文件)或配置文件(如果启动器是二进制文件)(ini / conf 文件)并找出 JVM 配置(java.library.path 指向的位置)。
If a java library (jar) uses a native library (dll on Windows or so on Linux) the chances are that it is a system wide and well known library (such as glibc on Linux) or a custom one. In the last case it is common to pack it within the jar, so you can just open it up with a ZIP decompressor (i.e. 7zip on Windows will do fine) and browse the files. You should see dll files if it is targeted to Windows, so files if targeted to a Unix platform, or even both. The native library files usually are left at the root level of the jar.
If the jar uses custom libraries but it is packed along with an application it is common to leave the native libraries in an external folder with other application files (in this case there is no consensus). In this case you should look for the application launcher (a bat / sh file) or the configuration file if the lanucher is binary (an ini / conf file) and find out the JVM configuration (where java.library.path points to).
最简单的方法可能是使用 jmap 或 pmap 来显示哪些 .so(共享对象)文件映射到 Java 进程中。如果除了 /lib、/usr/lib 或 Java lib 目录中的内容之外还有其他内容,则怀疑是 JNI。您还可以查看 /proc//maps 下 Java 进程的 /proc 条目。请参阅以下联机帮助页:
Probably the easiest way of doing this is using jmap or pmap to show which .so (shared object) files are mapped into your Java process. If there's anything other than stuff that's in /lib, /usr/lib or the Java lib directory it's a JNI suspect. You can also look at the /proc entry for the Java process under /proc/<pid>/maps. See the following manpages: