在处理 JNI 和 Maven 时,Projects With JNI是应该开始的参考。它涵盖的内容远远超过您当前的问题(“只是”使用依赖于 JNI 和本机库的库),但是,可以做更多事情的人可以做更少的事情。
如果您仔细阅读,您会发现使用 JNI 库的一种解决方案是将它们捆绑在特定于体系结构的 JAR 中,这样您就可以像依赖 Maven 的任何其他依赖项一样依赖它们。这实际上是 JOGL 版本 1.1.1 在 http://download.java.net/maven/2/net/java/dev/jogl/中的打包方式,有一个带有 Java 类的 JAR 工件和几个特定于体系结构的 JAR 工件与本机库。
jar 中归档的 JNI 库
我最终使用的解决方案是将编译的 jni 库与类文件一起存储在 jar 中。
这意味着对所有可能的架构进行交叉编译,或者更简单地说,为每个架构使用不同的 jar。后者非常适合我们的设置——我们几乎所有的机器都是 Linux-i386,带有少量的 win32 机器。
遗憾的是System.load()
无法从 jar 中加载库,因此我们需要一个自定义加载器,它在运行时将库提取到临时文件中;然而,这显然是可以实现的。
然后,正如所解释的,这个想法是使用自定义库加载器来加载本机库。好消息是这样的加载程序是“提供”的,如下所述。
库加载器
现在我们的 JNI 库在类路径中,所以我们需要一种加载它的方法。我创建了一个单独的项目,该项目将从类路径中提取 JNI 库,然后加载它们。在http://opensource.mxtelecom.com/maven/repo/com/wapmx/native/mx-native-loader/1.2/找到它
。显然,这是作为 pom 的依赖项添加的。
要使用它,请调用
com.wapmx.nativeutils.jniloader.NativeLoader.loadLibrary(libname)
. 更多信息在用于
NativeLoader
.
我通常更喜欢将这些东西包装在 try/catch 块中,如下所示:
public class Sqrt {
static {
try {
NativeLoader.loadLibrary("sqrt");
} catch (Throwable e) {
e.printStackTrace();
System.exit(1);
}
}
/* ... class body ... */
}
我们现在应该可以在 Maven 中进行 junit 测试了;一个 mvn 测试应该工作!它也应该可以在 IDE 中正常工作。
现在,要回答您的问题,如何:
如有必要,从此处自动下载特定于操作系统的 JOGL zip 文件(包含 4 个 jar 文件和一些本机库文件 (.so/.dll));或依赖于一个 Maven 项目,该项目是其中一个文件的包装器。
遗憾的是,JOGL 2.0 jar 在 java.net 的 Maven 存储库中不可用,因此您必须处理这个问题,要么将它们放在私有存储库中,要么在每个开发人员的本地存储库中手动安装它们。为此,请按照安装 3rd 方 JAR 指南mvn install:install-file
中的说明使用(而不是像您所做的那样,此目标用于将工件安装到远程存储库)。mvn deploy:deploy-file
就个人而言,我会从您提供的 URL下载 JOGL 2.0 ZIP ,像使用 JOGL 1.1.1 一样打包它(一个 Java JAR 和几个用于本地库的特定 JAR),然后现在将 JAR 安装在每个本地存储库中。然后,声明对 Java 工件的标准依赖关系,实际上,使用配置文件来实现特定于体系结构的依赖关系。像这样的东西:
<project>
...
<dependencies>
<dependency>
<groupId>net.java.dev.jogl</groupId>
<artifactId>jogl</artifactId>
<version>2.0-beta10</version>
</dependency>
...
</dependencies>
...
<profiles>
<profile>
<id>linux-i586</id>
<activation>
<os>
<arch>i386</arch>
<family>unix</family>
<name>linux</name>
</os>
</activation>
<dependencies>
<dependency>
<groupId>net.java.dev.jogl.jogl-linux-i586</groupId>
<artifactId>jogl-linux-i586</artifactId>
<version>2.0-beta10</version>
</dependency>
</dependencies>
</profile>
...
</profiles>
...
</project>
不要忘记添加自定义库加载器和依赖项所需的存储库:
<project>
<repositories>
<repository>
<id>opensource.mxtelecom.com</id>
<url>http://opensource.mxtelecom.com/maven/repo</url>
</repository>
...
<repositories>
...
<dependencies>
<dependency>
<groupId>com.wapmx.native</groupId>
<artifactId>mx-native-loader</artifactId>
<version>1.2</version>
</dependency>
...
</dependencies>
...
</project>
关于你问题的第二部分:
适当地解压缩该 zip 文件,以便 (...)
正如我所解释的,您实际上不会依赖于 ZIP 文件,而是依赖于 JAR,并且在开发过程中也不需要解压缩它们,也不需要分发您的项目。对于分发,您只需要创建一个包含依赖项的 jar。这可以通过 maven-assembly-plugin 来完成。例如,有关此问题的更多详细信息,请参见此答案。