在处理 JNI 和 Maven 时,使用 JNI 的项目是应该开始的参考。它涵盖了比你当前的问题(“只是”使用依赖于JNI和本机库的库)要多得多,但是,好吧,谁能做更多的事情,谁能做的就更少。
如果你仔细阅读它,你会发现使用JNI库的一个解决方案是将它们捆绑在特定于架构的JAR中,这样你就可以像从Maven的角度来看任何其他依赖项一样依赖它们。这实际上是JOGL版本1.1.1打包在 http://download.java.net/maven/2/net/java/dev/jogl/ 中的方式,有一个JAR工件带有Java类,几个特定于架构的JAR工件与本机库。
在 jar 中存档的 JNI 库
我最终使用的解决方案是将编译的jni库与类文件一起存储在jar中。
这意味着要么针对所有可能的体系结构进行交叉编译,要么更简单地说,为每个体系结构使用不同的 jar。后者非常适合我们的设置 - 我们几乎所有的机器都是Linux-i386,只有少量的win32盒子。
可悲的是,无法应对从jar中加载库,因此我们需要一个自定义加载器,它将库提取到运行时的临时文件;然而,这显然是可以实现的。System.load()
然后,如前所述,这个想法是使用自定义库加载器来加载本机库。好消息是,这样的加载器是“提供”的,如下所述。
库加载器
现在,我们的 JNI 库位于类路径上,因此我们需要一种加载它的方法。我创建了一个单独的项目,它将从类路径中提取JNI库,然后加载它们。在 http://opensource.mxtelecom.com/maven/repo/com/wapmx/native/mx-native-loader/1.2/ 找到它。显然,这是作为对 pom 的依赖关系添加的。
要使用它,请调用 。有关详细信息,请参见 的 javadoc。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 ... */
}
我们现在应该处于我们的 junit 测试从 maven 开始工作的地步;一个 mvn 测试应该有效!它还应该在 IDE 中正常工作。
现在,要回答您的问题,如何:
如有必要,从此处自动下载特定于操作系统的 JOGL zip 文件(包含 4 个 jar 文件和一些本机库文件 (.so/.dll));或者依赖于 Maven 项目,该项目是其中一个文件的包装器。
可悲的是,JOGL 2.0 jar在 java.net 的Maven存储库中不可用,因此您必须处理这个问题,并将它们在私有存储库中提供,或者在每个开发人员的本地存储库中手动安装它们。为此,请按照安装第三方 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来完成。有关此内容的更多详细信息,请参阅此答案。