Maven and the JOGL library?

When dealing with JNI and Maven, Projects With JNI is the reference one should start with. It covers a lot more than your current problem (which is "just" using a library that relies on JNI and native libraries) but, well, he who can do more can do less.

If you read it carefully, you'll see that one solution to use JNI libraries is to bundle them in architecture specific JARs so that you can depend on them like any other dependency from a Maven point of view. This is actually how JOGL version 1.1.1 is packaged in http://download.java.net/maven/2/net/java/dev/jogl/, there is one JAR artifact with the Java classes and several architecture specific JARs artifacts with the native libraries.

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.

Then, as explained, the idea is to use a custom library loader to load the native library. The good news is that such a loader is "provided" as explained below.

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.

Now, to answer your questions, how to:

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.

Sadly, JOGL 2.0 jars aren't available in the Maven repository of java.net so you'll have to deal with that and either make them available in a private repository or install them manually in the local repository of each developer. To do so, use mvn install:install-file as documented in the Guide to installing 3rd party JARs (and not mvn deploy:deploy-file as you did, this goal is used to install artifacts to a remote repository).

Personally, I would download JOGL 2.0 ZIPs from the URL you provided, package it as they did with JOGL 1.1.1 (one Java JAR and several specific JARs for native libraries) and install the JARs in each local repository for now. Then, declare a standard dependency on the Java artifact and, indeed, use profiles for the architecture specific dependency. Something like this:

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

Don't forget to add the repository required for the custom library loader and the dependency:

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

Regarding the second part of your question:

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

As I explained, you actually won't depend on ZIP files but on JARs and you won't need to uncompress them neither during development nor to distribute your project. For the distribution, you'll just need to create a jar including the dependencies. This can be done with the maven-assembly-plugin. See this answer for example for more details on this.


Jogamp now contains support for Maven, for the jogl components (jocl and joal support is forthcoming). As of 2.0-rc11, packages are pushed to Maven Central.

Just put this to your 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 will pull all of the dependencies the next time you attempt to build the project.

Read more here on the wiki