【问题标题】:Maven and the JOGL library?Maven 和 JOGL 库?
【发布时间】:2010-12-30 01:57:50
【问题描述】:

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

  1. 如有必要,自动从here 下载特定于操作系统的 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。 (激活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 文件都不同。

【问题讨论】:

  • 顺便说一句,我知道 java.net 存储库中已经存在一个 JOGL 1 Maven 项目,我正在寻找使用我找不到现有存储库/项目的 JOGL 2为了。你将不得不比这更深入地谷歌:)
  • 顺便说一句,使用 Apache Ivy 这将是微不足道的。好吧,从某种意义上说,一旦您学会了如何为自定义依赖项创建自己的私有存储库,那么这样做就很简单了。

标签: java maven maven-2 build-process jogl


【解决方案1】:

在处理 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 工件。

JNI 库归档在 jar 中

我最终使用的解决方案是 将编译好的 jni 库存放在 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)。 更多信息在 javadoc 中 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 存储库中不可用,因此您必须处理这个问题,要么将它们提供在私有存储库中,要么将它们手动安装到每个开发人员的本地存储库中。为此,请使用Guide to installing 3rd party JARs 中记录的mvn install:install-file(而不是像您那样使用mvn deploy:deploy-file,此目标用于将工件安装到远程存储库)。

就我个人而言,我会从您提供的the URL 下载 JOGL 2.0 ZIP,像使用 JOGL 1.1.1 一样打包它(一个 Java JAR 和几个用于本地库的特定 JAR),然后暂时在每个本地存储库中安装 JAR .然后,声明对 Java 工件的标准依赖关系,实际上,使用 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>

关于你问题的第二部分:

适当地解压缩该 zip 文件,以便 (...)

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

【讨论】:

  • 我不喜欢自定义加载器方法,后来我切换到了 Ant,现在我对它非常满意。但是,您的回答是迄今为止对该问题最详细和信息最丰富的回答,因此我将其标记为已接受。
  • 这里有 Maven 存储库,显然是:jogamp.org/deployment/maven。但是尝试将它们与 Simple Build Tool 一起使用会报告没有 ivy.xml...
  • 这需要列出每个平台的本地依赖项。 JOGL 提供了一个 jogl-all maven 依赖项——如何使用?
  • codehaus 链接不见了; here is the archived version
【解决方案2】:

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

把这个放到你的 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 将在您下次尝试构建项目时提取所有依赖项。

Read more here on the wiki

【讨论】:

  • 这里几乎所有其他答案都被这个答案所取代,除了关于处理本机库的部分。
【解决方案3】:

这里有一个 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. ...

【讨论】:

    【解决方案4】:

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

    • 告诉开发人员自行安装 JOGL,然后像使用 Java3d 一样将 JOGL 库视为系统依赖项

      <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>
      
    • 将所有 jar 和系统相关库放在自己的存储库中,并为它们创建合适的 pom

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

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

    【讨论】:

      【解决方案5】:

      这里是我的 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>
      

      【讨论】:

      • 这真的很棒。我开始了一些不同的东西,但自动下载是一个不错的选择。
      【解决方案6】:

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

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

      【讨论】:

        【解决方案7】:

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

        【讨论】:

        • 或者你对放弃 Maven 并选择 Ant 有什么看法?
        • 也许比 maven 更适合您的情况。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多