28

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

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

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

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

我尝试基于 JOGL jar 文件创建 Maven 存储库,然后将 JOGL jar 文件项目添加为我的项目的依赖项;依赖项已下载,但未使用。我不知道 jar 文件的去向或如何使用它、解压它等等。这是我使用的命令。

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

4

7 回答 7

25

在处理 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 来完成。例如,有关此问题的更多详细信息,请参见此答案。

于 2009-12-28T11:37:07.940 回答
15

Jogamp 现在包含对 Maven 和 jogl 组件的支持(即将推出对 jocl 和 joal 的支持)。从 2.0-rc11 开始,包被推送到 Maven 中心。

把它放到你的 pom 中:

 <dependencies>
   <dependency>
     <groupId>org.jogamp.gluegen</groupId>
     <artifactId>gluegen-rt-main</artifactId>
     <version>2.0-rc11</version>
   </dependency>
   <dependency>
     <groupId>org.jogamp.jogl</groupId>
     <artifactId>jogl-all-main</artifactId>
     <version>2.0-rc11</version>
   </dependency>
 </dependencies>

下次您尝试构建项目时,Maven 将提取所有依赖项。

在 wiki 上阅读更多内容

于 2012-11-24T10:03:20.337 回答
6

这里有一个 JOGL 2.0 的 maven repo:http: //jogamp.org/deployment/maven/

我使用 SBT 来构建我的项目。您需要添加到的解析器build.sbt

resolvers += MavenRepository("jogamp", "http://jogamp.org/deployment/maven")

以及对基本 jogl 库的依赖:

libraryDependencies += "org.jogamp.jogl" % "jogl-all" % "2.0-rc9"

在 maven xml 文件中,这将类似于(根据this):

 <settings>
   <profiles>
     <profile>
       <id>jogamp</id>
       <activation>
         <activeByDefault>true</activeByDefault> 
       </activation>
       <repositories>
         <repository>
           <id>jogamp-remote</id>
           <name>jogamp test mirror</name>
           <url>http://www.jogamp.org/deployment/maven/</url>
           <layout>default</layout>
         </repository>
       </repositories>
     </profile>
   </profiles>
 </settings>

依赖声明为:

<dependency>
  <groupId>org.jogamp.jogl</groupId>
  <artifactId>jogl-all</artifactId>
  <version>2.0-rc9</version>
</dependency>

要自动下载正确的本机 jar,在 sbt 中我执行以下操作:

sys.props("os.name") match {
  case "Linux" => "org.jogamp.jogl" % "jogl-all-natives-linux-i586" % "2.0-rc9"
  ... etc. ...
于 2012-07-03T18:57:24.593 回答
5

我不知道 JOGL 库,但我有使用 Java3d 的经验,它具有相同的安装/构建问题。有两种方法可以实现这一点:

  • 告诉开发人员自行安装 JOGL,然后将 JOGL 库视为系统依赖项,就像我们对 Java3d 所做的那样

    <dependency>
        <groupId>javax.java3d</groupId>
        <artifactId>j3dcore</artifactId>
        <version>1.5.1</version>
        <scope>system</scope>
        <systemPath>${java.home}/lib/ext/j3dcore.jar</systemPath>
    </dependency>
    
  • 将所有 jars 和系统依赖库放在自己的存储库中并为它们创建合适的 pom

如果您强烈希望使用 JOGL 的 Maven 安装实现自动化,您可以尝试使用maven-antrun-plugin或创建自己的 Maven 插件来处理安装(一个很好的例子是Cargo下载服务器并解压缩它)。

我考虑使用第一个选项 - 告诉开发人员安装 JOGL。在我们的例子中,Java3d 应用程序是由 Java WebStart 分发的,因此对于他们来说,Java3d 的安装是由 WebStart 完全自动化的。

于 2009-12-28T07:45:18.810 回答
2

这里是我的 Ant build.xml 文件的一部分,用于下载和解压缩 JOGL 库(2.0 beta 10),以供参考。

<target name="libraries" depends="libraries.jogl" />

<target name="libraries.jogl.check">
    <condition property="libraries.jogl.exists">
        <available file="lib/jogl" />
    </condition>
</target>

<target name="libraries.jogl" depends="libraries.jogl.check" unless="libraries.jogl.exists">
    <condition property="joglostype" value="windows-i586">
        <and>
            <os family="windows" />
            <or>
                <os arch="i386" />
                <os arch="x86" />
            </or>
        </and>
    </condition>
    <condition property="joglostype" value="windows-amd64">
        <and>
            <os family="windows" />
            <os arch="amd64" />
        </and>
    </condition>
    <condition property="joglostype" value="linux-i586">
        <and>
            <os name="Linux" />
            <or>
                <os arch="i386" />
                <os arch="x86" />
            </or>
        </and>
    </condition>
    <condition property="joglostype" value="linux-amd64">
        <and>
            <os name="Linux" />
            <or>
                <os arch="AMD64" />
                <os arch="x86_64" />
            </or>
        </and>
    </condition>
    <echo>Detected operating system: ${joglostype}</echo>
    <echo>(if invalid OS, update ant build file)</echo>

    <mkdir dir="lib" />
    <get src="http://download.java.net/media/jogl/builds/archive/jsr-231-2.0-beta10/jogl-2.0-${joglostype}.zip" dest="lib/jogl.zip" usetimestamp="true" />

    <mkdir dir="lib/jogl" />
    <unzip src="lib/jogl.zip" dest="lib/jogl">
        <patternset>
            <include name="**/gluegen-rt.jar" />
            <include name="**/jogl.all.jar" />
            <include name="**/nativewindow.all.jar" />
            <include name="**/newt.all.jar" />
            <include name="**/*.so" />
            <include name="**/*.dll" />
        </patternset>
        <mapper type="flatten" />
    </unzip>
</target>
于 2010-02-23T03:32:07.597 回答
1

此脚本将从 URL 下载版本并将其安装到本地(命名)存储库。 https://gist.github.com/1624599

示例用法:./install_jogl_maven http://jogamp.org/deployment/v2.0-rc5 path_to_local_repo 2.0-rc5

于 2012-01-17T04:13:55.123 回答
0

没有简单的方法可以做到这一点。尝试是否可以配置maven-assembly-plugin以构建可执行 jar 并使用您的代码打包正确的文件。您不能使用 maven 依赖管理来实现此目的,因为您需要 ZIP 内容而不是 ZIP 本身。你可以试试maven-ant-plugin

于 2009-12-27T20:16:54.663 回答