如何在 JAR 中捆绑原生库和 JNI 库?
有问题的图书馆是东京内阁.
我希望将本机库、JNI 库和所有 Java API 类放在一个 JAR 文件中,以避免重新分发的麻烦.
I want is to have the native library, JNI library, and all Java API classes in one JAR file to avoid redistribution headaches.
似乎有在 GitHub 上尝试这样做,但是
- 不包含实际的原生库,仅包含 JNI 库.
- 它似乎是特定于 Leiningen 的原生依赖插件(它不能作为可再分发).
- It does not include the actual native library, only JNI library.
- It seems to be specific to Leiningen's native dependencies plugin (it won't work as a redistributable).
问题是,我可以将所有内容捆绑在一个 JAR 中并重新分发吗?如果是,怎么做?
The question is, can I bundle everything in one JAR and redistribute it? If yes, how?
P.S.:是的,我知道它可能会影响可移植性.
P.S.: Yes, I realize it may have portability implications.
推荐答案
可以创建一个包含所有依赖项的单个 JAR 文件,包括一个或多个平台的本机 JNI 库.基本机制是使用 System.load(File) 来加载库,而不是使用典型的 System.loadLibrary(String) 来搜索 java.library.path 系统属性.这种方法使安装更加简单,因为用户不必在他的系统上安装 JNI 库,但代价是可能不支持所有平台,因为平台的特定库可能不包含在单个 JAR 文件中.
It is possible to create a single JAR file with all dependencies including the native JNI libraries for one or more platforms. The basic mechanism is to use System.load(File) to load the library instead of the typical System.loadLibrary(String) which searches the java.library.path system property. This method makes installation much simpler as the user does not have to install the JNI library on his system, at the expense, however, that all platforms might not be supported as the specific library for a platform might not be included in the single JAR file.
流程如下:
- 在平台特定位置的 JAR 文件中包含本机 JNI 库,例如 NATIVE/${os.arch}/${os.name}/libname.lib
- 在主类的静态初始化器中创建代码以
- 计算当前的 os.arch 和 os.name
- 使用 Class.getResource(String) 在 JAR 文件中的预定义位置查找库
- 如果存在,将其解压缩到临时文件并使用 System.load(File) 加载.
我为 jzmq 添加了功能,它是 ZeroMQ 的 Java 绑定(无耻插件).代码可以在 这里.jzmq 代码使用混合解决方案,因此如果无法加载嵌入式库,代码将恢复为沿 java.library.path 搜索 JNI 库.
I added functionality to do this for jzmq, the Java bindings of ZeroMQ (shameless plug). The code can be found here. The jzmq code uses a hybrid solution so that if an embedded library cannot be loaded, the code will revert to searching for the JNI library along the java.library.path.
相关文章