java - Maven 和 JOGL 库?

标签 java maven maven-2 build-process jogl

过去几天我一直在空闲时间学习 Maven,但似乎不知道如何组织项目以便使用 JOGL 库。我最好喜欢以下内容:

  1. 如有必要,自动从 here 下载特定于操作系统的 JOGL zip 文件(包含4个jar文件和一些 native 库文件(.so/.dll));或依赖一个 Maven 项目,该项目是其中一个文件的包装器。
  2. 适当解压缩该 zip 文件,以便:
    1. 将 jar 文件添加到类路径并根据需要进行部署,并且
    2. 将原生库文件添加到最终的 jar 文件中(这是否可以自动使用它们,还是我需要更多的参与?)

我认为我的部分问题是我没有完全理解 JOGL 的使用,运行代码时在哪里放置原生库等。我需要回到基础并编写一个 JOGL hello world,从命令行编译它并从命令行运行它,以确切了解它对 native 库的目录位置的要求;实际上,我现在可以去做。

对于第 1 项,我发现了一些特定于操作系统的功能;可以根据系统的属性(包括操作系统)激活 Maven 配置文件。因此,我可以激活一个 Windows 配置文件,该配置文件依赖于特定于 Windows 的 JOGL 库,与 Linux 相同,并且都具有 64 位的 alter ego。 (激活 official docs/unofficial docs 。)

我尝试过基于 JOGL jar 文件创建 Maven 存储库,然后将 JOGL jar 文件项目添加为我的项目的依赖项;依赖项已下载,但未使用。我不知道 jar 文件去哪里或如何使用它、解压它等等。Here is the command I used.

因此,简而言之:JOGL 由四个 .jar 文件和一些本地库组成。如何将这些文件集成到我的 Maven 项目中,以便我可以使用 Maven 编写一个 JOGL 应用程序来处理我的构建过程? 此外,我如何根据操作系统使用不同的文件集,因为当然Windows、Linux 和 Mac 之间的原生库甚至 .jar 文件都不同。

最佳答案

在处理 JNI 和 Maven 时,Projects With JNI引用一个应该开始。它涵盖的内容远远超过您当前的问题(“只是”使用依赖于 JNI 和 native 库的库),但是,可以做得更多的人可以做得更少。

如果您仔细阅读,您会发现使用 JNI 库的一种解决方案是将它们捆绑在特定于体系结构的 JAR 中,这样您就可以像依赖 Maven 的任何其他依赖项一样依赖它们。这实际上是 JOGL 版本 1.1.1 打包在 http://download.java.net/maven/2/net/java/dev/jogl/ 中的方式,有一个带有 Java 类的 JAR Artifact 和几个带有 native 库的特定于体系结构的 JAR Artifact 。

JNI library archived within the jar

The solution I ended up using was to store the compiled jni library in the jar alongside the class files.

This means either cross-compiling for all possible architectures, or more simply, having a different jar for each architecture. This latter fits quite well with our setup - where almost all of our machines are Linux-i386, with a smattering of win32 boxes.

Sadly System.load() can't cope with loading libraries from within a jar, so we'll therefore need a custom loader which extracts the library to a temporary file at runtime; this is obviously achievable, however.

然后,正如解释的那样,想法是使用自定义库加载器来加载 native 库。好消息是这样的加载器是“提供”的,如下所述。

Library loader

We now have our JNI library on the class path, so we need a way of loading it. I created a separate project which would extract JNI libraries from the class path, then load them. Find it at http://opensource.mxtelecom.com/maven/repo/com/wapmx/native/mx-native-loader/1.2/. This is added as a dependency to the pom, obviously.

To use it, call com.wapmx.nativeutils.jniloader.NativeLoader.loadLibrary(libname). More information is in the javadoc for NativeLoader.

I generally prefer to wrap such things in a try/catch block, as follows:

public class Sqrt {
    static {
        try {
            NativeLoader.loadLibrary("sqrt");
        } catch (Throwable e) {
            e.printStackTrace();
            System.exit(1);
        }
    }
    /* ... class body ... */
}

We should now be at the point where our junit tests work from maven; a mvn test should work! It should also work fine from an IDE.

现在,回答您的问题,如何:

Automatically download, if necessary, the OS-specific JOGL zip file from here (contains 4 jar files and some native library files (.so/.dll)); or depend on a Maven project which is a wrapper of one of the files.

遗憾的是,JOGL 2.0 jar 在 java.net 的 Maven 存储库中不可用,因此您必须解决这个问题,要么将它们放在私有(private)存储库中,要么手动将它们安装在每个开发人员的本地存储库中。为此,请使用 Guide to installing 3rd party JARs 中记录的 mvn install:install-file (而不是像您所做的那样 mvn deploy:deploy-file,此目标用于将 Artifact 安装到远程存储库)。

就我个人而言,我会从 the URL 下载 JOGL 2.0 ZIP。您提供了,像使用 JOGL 1.1.1 一样打包它(一个 Java JAR 和几个用于本地库的特定 JAR),现在在每个本地存储库中安装 JAR。然后,声明对 Java Artifact 的标准依赖,实际上,使用 profiles对于架构特定的依赖关系。像这样的:

<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>

关于你问题的第二部分:

Unzip that zip file appropriately, so that (...)

正如我所解释的,您实际上不会依赖于 ZIP 文件,而是依赖于 JAR,而且您在开发过程中和分发项目时都不需要解压缩它们。对于分发,您只需要创建一个包含依赖项的 jar。这可以通过 maven-assembly-plugin 来完成。见 this answer例如有关此的更多详细信息。

关于java - Maven 和 JOGL 库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1962718/

相关文章:

java - 如何解决Maven项目中的central.maven.org : Unknown host central. maven.org?

java - 使用 maven 构建耳朵

java - maven 使用简单的命令行安装和部署 3rd 方依赖项

java - 如何在 if 语句周围添加 try 和 catch?

java - 无法解析包含特殊字符的值?使用 sax 解析器

D2 安装后出现 java.lang.ClassCastException

maven - 什么是 Maven 相当于 gradle '+' ?

maven - 即使我没有在任何地方配置它,Android Gradle Build 也会尝试访问 JCenter

java - 限制 Java maven 插件配置参数

java - 从 JFrame 中删除 JPanel,太慢了