JogAmp JAR File Handling: Difference between revisions

From JogampWiki
Jump to navigation Jump to search
(→‎Fat-Jar: creation with Ant)
(→‎Ant: Adds the missing inclusion filters into the zip fileset in order to repair Windows support as it relies on these executables)
 
(5 intermediate revisions by 2 users not shown)
Line 67: Line 67:
=== Creation ===
=== Creation ===


== Ant ==
==== Ant ====
You can use the [http://ant.apache.org/manual/Tasks/jar.html Ant jar task] to create a fat JAR. You must avoid file names collision, i.e you must exclude the file(s) with the same name(s) in multiple JARs. The following line just keeps the strict minimum to make JogAmp work and should be used with the [http://ant.apache.org/manual/Tasks/jar.html Ant jar task]:
You can use the [http://ant.apache.org/manual/Tasks/jar.html Ant jar task] to create a fat JAR. You must avoid file names collision, i.e you must exclude the file(s) with the same name(s) in multiple JARs. You can use [https://ant.apache.org/manual/Tasks/manifest.html Ant manifest task] to create a manifest file. The following line just keeps the strict minimum to make JogAmp work and should be used with the [http://ant.apache.org/manual/Tasks/jar.html Ant jar task]:


<zipfileset src="jogamp-fat.jar" includes="**/*.class,**/*.png,**/*.glsl,**/*.vp,**/*.fp,**/*.bvp,**/*.bfp,**/*.so,**/*.jnilib,**/*.dylib,**/*.dll,**/.bin"/>
<zipfileset src="jogamp-fat.jar" includes="**/*.class,**/*.png,**/*.glsl,**/*.vp,**/*.fp,**/*.bvp,**/*.bfp,**/*.so,**/*.jnilib,**/*.dylib,**/*.dll,**/*.bin,**/*.defl"/>
 
==== Maven ====
[http://maven.apache.org/plugins/maven-shade-plugin/index.html Maven Shade Plugin] is the recommended plugin to use to create fat JARs with [http://maven.apache.org Maven]. [http://maven.apache.org/plugins/maven-shade-plugin/examples/executable-jar.html This example] shows how to set some entries in the manifest file.
 
==== Maven Assembly Plugin ====
 
An example descriptor file that produces a fat jar containing all of the calling project's dependencies, and the JOGL/GlueGen native jar files placed into the correct directory inside the jar:
 
<pre>
<assembly
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
  xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
 
  <id>with-dependencies</id>
  <includeBaseDirectory>false</includeBaseDirectory>
 
  <formats>
    <format>jar</format>
  </formats>
 
  <dependencySets>
 
    <!-- Unpack everything that isn't a JOGL or GlueGen library -->
    <dependencySet>
      <outputDirectory>/</outputDirectory>
      <useProjectArtifact>true</useProjectArtifact>
      <scope>runtime</scope>
      <unpack>true</unpack>
      <unpackOptions>
        <excludes>
          <exclude>libgluegen-rt*</exclude>
          <exclude>libjogl_desktop.*</exclude>
          <exclude>libjogl_mobile.*</exclude>
          <exclude>libnativewindow_awt.*</exclude>
          <exclude>libnativewindow_macosx.*</exclude>
          <exclude>libnativewindow_x11.*</exclude>
          <exclude>libnewt.*</exclude>
        </excludes>
      </unpackOptions>
    </dependencySet>
 
    <!-- Place the natives for the popular platforms into the correct place -->
    <!-- in the resulting jar file. -->
 
    <dependencySet>
      <outputDirectory>/natives/linux-amd64/</outputDirectory>
      <useProjectArtifact>true</useProjectArtifact>
      <scope>runtime</scope>
      <unpack>true</unpack>
      <includes>
        <include>org.jogamp.gluegen:gluegen-rt:jar:natives-linux-amd64</include>
        <include>org.jogamp.jogl:jogl-all:jar:natives-linux-amd64</include>
      </includes>
      <unpackOptions>
        <includes><include>*.so</include></includes>
      </unpackOptions>
    </dependencySet>
 
    <dependencySet>
      <outputDirectory>/natives/linux-i586/</outputDirectory>
      <useProjectArtifact>true</useProjectArtifact>
      <scope>runtime</scope>
      <unpack>true</unpack>
      <includes>
        <include>org.jogamp.gluegen:gluegen-rt:jar:natives-linux-i586</include>
        <include>org.jogamp.jogl:jogl-all:jar:natives-linux-i586</include>
      </includes>
      <unpackOptions>
        <includes><include>*.so</include></includes>
      </unpackOptions>
    </dependencySet>
 
    <dependencySet>
      <outputDirectory>/natives/windows-amd64/</outputDirectory>
      <useProjectArtifact>true</useProjectArtifact>
      <scope>runtime</scope>
      <unpack>true</unpack>
      <includes>
        <include>org.jogamp.gluegen:gluegen-rt:jar:natives-windows-amd64</include>
        <include>org.jogamp.jogl:jogl-all:jar:natives-windows-amd64</include>
      </includes>
      <unpackOptions>
        <includes><include>*.dll</include></includes>
      </unpackOptions>
    </dependencySet>
 
    <dependencySet>
      <outputDirectory>/natives/windows-i586/</outputDirectory>
      <useProjectArtifact>true</useProjectArtifact>
      <scope>runtime</scope>
      <unpack>true</unpack>
      <includes>
        <include>org.jogamp.gluegen:gluegen-rt:jar:natives-windows-i586</include>
        <include>org.jogamp.jogl:jogl-all:jar:natives-windows-i586</include>
      </includes>
      <unpackOptions>
        <includes><include>*.dll</include></includes>
      </unpackOptions>
    </dependencySet>
 
    <dependencySet>
      <outputDirectory>/natives/macosx-universal/</outputDirectory>
      <useProjectArtifact>true</useProjectArtifact>
      <scope>runtime</scope>
      <unpack>true</unpack>
      <includes>
        <include>org.jogamp.gluegen:gluegen-rt:jar:natives-macosx-universal</include>
        <include>org.jogamp.jogl:jogl-all:jar:natives-macosx-universal</include>
      </includes>
      <unpackOptions>
        <includes><include>*.jnilib</include></includes>
      </unpackOptions>
    </dependencySet>
  </dependencySets>
</assembly>
</pre>
 
This can be called in the usual manner (assuming that the descriptor file is in <tt>src/main/assembly/application.xml</tt>):
 
<pre>
<plugin>
  <artifactId>maven-assembly-plugin</artifactId>
  <configuration>
    <archive>
      <manifest>
        <mainClass>com.example.main.SomeMainClassHere</mainClass>
      </manifest>
    </archive>
    <descriptors>
      <descriptor>src/main/assembly/application.xml</descriptor>
    </descriptors>
  </configuration>
  <executions>
    <execution>
      <id>make-assembly</id>
      <phase>package</phase>
      <goals>
        <goal>single</goal>
      </goals>
    </execution>
  </executions>
</plugin>
</pre>
 
The result is an executable jar file, suffixed with <tt>-with-dependencies.jar</tt> that will execute <tt>com.example.main.SomeMainClassHere</tt> and that will correctly find all of the native libraries at run-time.


== One-Jar ==
== One-Jar ==

Latest revision as of 10:09, 4 November 2015

Native JAR Files

See Native JAR Files explained.

Native JAR files are loaded automatically.

Applet / JNLP Usage

A short copy is included in the static page JOGL Deployment using NApplet.

Custom Bundling

Multi-Jar

Multi-Jar

This configuration is discouraged, since such deployment removes our artifacts as stored in the jar's manifest file, which helps identifying the jogamp modules for bug reports etc.

However, since we don't want to patronize our user base, we support this feature with our native JAR lib loading mechanism.

It is possible to merge all modules together, i.e.

 multi.jar:
   gluegen-rt.jar
   jogl-all.jar
   user-app.jar
 multi-natives-<os.and.arch>.jar:
   gluegen-rt-natives-<os.and.arch>.jar
   jogl-all-natives-<os.and.arch>.jar

A combination with Fat-Jar is possible.

Fat-Jar

Discouraged Fat-Jar

This configuration is discouraged, since such deployment removes our artifacts as stored in the jar's manifest file, which helps identifying the jogamp modules for bug reports etc.

Furthermore, adding all native library files for all supported platforms will add-up to +3M of _compressed_ jar data!

However, since we don't want to patronize our user base, we support this feature with our native JAR lib loading mechanism.

Usage

If the modules's jar file contains the folder 'natives/<os.and.arch>/' we assume a fat-jar and attempt to load all native libraries from the same.

If we don't have a fat-jar or if fat-jar loading doesn't result in extracted native libraries, we assume a regular slim jar file.

Layout:

 /com/lala1/Lala1.class
 /com/lala2/Lala2.class
 /natives/<os.and.arch>/libLala1.so
 /natives/<os.and.arch>/libLala2.so

A combination w/ Multi-Jar is of course possible.

Creation

Ant

You can use the Ant jar task to create a fat JAR. You must avoid file names collision, i.e you must exclude the file(s) with the same name(s) in multiple JARs. You can use Ant manifest task to create a manifest file. The following line just keeps the strict minimum to make JogAmp work and should be used with the Ant jar task:

<zipfileset src="jogamp-fat.jar" includes="**/*.class,**/*.png,**/*.glsl,**/*.vp,**/*.fp,**/*.bvp,**/*.bfp,**/*.so,**/*.jnilib,**/*.dylib,**/*.dll,**/*.bin,**/*.defl"/>

Maven

Maven Shade Plugin is the recommended plugin to use to create fat JARs with Maven. This example shows how to set some entries in the manifest file.

Maven Assembly Plugin

An example descriptor file that produces a fat jar containing all of the calling project's dependencies, and the JOGL/GlueGen native jar files placed into the correct directory inside the jar:

<assembly
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
  xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">

  <id>with-dependencies</id>
  <includeBaseDirectory>false</includeBaseDirectory>

  <formats>
    <format>jar</format>
  </formats>

  <dependencySets>

    <!-- Unpack everything that isn't a JOGL or GlueGen library -->
    <dependencySet>
      <outputDirectory>/</outputDirectory>
      <useProjectArtifact>true</useProjectArtifact>
      <scope>runtime</scope>
      <unpack>true</unpack>
      <unpackOptions>
        <excludes>
          <exclude>libgluegen-rt*</exclude>
          <exclude>libjogl_desktop.*</exclude>
          <exclude>libjogl_mobile.*</exclude>
          <exclude>libnativewindow_awt.*</exclude>
          <exclude>libnativewindow_macosx.*</exclude>
          <exclude>libnativewindow_x11.*</exclude>
          <exclude>libnewt.*</exclude>
        </excludes>
      </unpackOptions>
    </dependencySet>

    <!-- Place the natives for the popular platforms into the correct place -->
    <!-- in the resulting jar file. -->

    <dependencySet>
      <outputDirectory>/natives/linux-amd64/</outputDirectory>
      <useProjectArtifact>true</useProjectArtifact>
      <scope>runtime</scope>
      <unpack>true</unpack>
      <includes>
        <include>org.jogamp.gluegen:gluegen-rt:jar:natives-linux-amd64</include>
        <include>org.jogamp.jogl:jogl-all:jar:natives-linux-amd64</include>
      </includes>
      <unpackOptions>
        <includes><include>*.so</include></includes>
      </unpackOptions>
    </dependencySet>

    <dependencySet>
      <outputDirectory>/natives/linux-i586/</outputDirectory>
      <useProjectArtifact>true</useProjectArtifact>
      <scope>runtime</scope>
      <unpack>true</unpack>
      <includes>
        <include>org.jogamp.gluegen:gluegen-rt:jar:natives-linux-i586</include>
        <include>org.jogamp.jogl:jogl-all:jar:natives-linux-i586</include>
      </includes>
      <unpackOptions>
        <includes><include>*.so</include></includes>
      </unpackOptions>
    </dependencySet>

    <dependencySet>
      <outputDirectory>/natives/windows-amd64/</outputDirectory>
      <useProjectArtifact>true</useProjectArtifact>
      <scope>runtime</scope>
      <unpack>true</unpack>
      <includes>
        <include>org.jogamp.gluegen:gluegen-rt:jar:natives-windows-amd64</include>
        <include>org.jogamp.jogl:jogl-all:jar:natives-windows-amd64</include>
      </includes>
      <unpackOptions>
        <includes><include>*.dll</include></includes>
      </unpackOptions>
    </dependencySet>

    <dependencySet>
      <outputDirectory>/natives/windows-i586/</outputDirectory>
      <useProjectArtifact>true</useProjectArtifact>
      <scope>runtime</scope>
      <unpack>true</unpack>
      <includes>
        <include>org.jogamp.gluegen:gluegen-rt:jar:natives-windows-i586</include>
        <include>org.jogamp.jogl:jogl-all:jar:natives-windows-i586</include>
      </includes>
      <unpackOptions>
        <includes><include>*.dll</include></includes>
      </unpackOptions>
    </dependencySet>

    <dependencySet>
      <outputDirectory>/natives/macosx-universal/</outputDirectory>
      <useProjectArtifact>true</useProjectArtifact>
      <scope>runtime</scope>
      <unpack>true</unpack>
      <includes>
        <include>org.jogamp.gluegen:gluegen-rt:jar:natives-macosx-universal</include>
        <include>org.jogamp.jogl:jogl-all:jar:natives-macosx-universal</include>
      </includes>
      <unpackOptions>
        <includes><include>*.jnilib</include></includes>
      </unpackOptions>
    </dependencySet>
  </dependencySets>
</assembly>

This can be called in the usual manner (assuming that the descriptor file is in src/main/assembly/application.xml):

<plugin>
  <artifactId>maven-assembly-plugin</artifactId>
  <configuration>
    <archive>
      <manifest>
        <mainClass>com.example.main.SomeMainClassHere</mainClass>
      </manifest>
    </archive>
    <descriptors>
      <descriptor>src/main/assembly/application.xml</descriptor>
    </descriptors>
  </configuration>
  <executions>
    <execution>
      <id>make-assembly</id>
      <phase>package</phase>
      <goals>
        <goal>single</goal>
      </goals>
    </execution>
  </executions>
</plugin>

The result is an executable jar file, suffixed with -with-dependencies.jar that will execute com.example.main.SomeMainClassHere and that will correctly find all of the native libraries at run-time.

One-Jar

One-Jar

One-Jar is incomplete, i.e. it does not provide a URL handler for it's jar-in-jar resources - hence we would need to implement this functionality manually.

See One-Jar lacks of URLHandler ...

For now, one can use Eclipse working jar-in-jar feature (see below). Since Eclipse is under an open source license, one should be able to locate the source code and include in a standalone toolkit, if so required.

JarMatey

JarMatey is an open source tool for creating standalone self-executing JARs, similar to One-Jar but with a graphical user interface and no support for build tools (Ant, Maven). You can find a detailed tutorial about it here.

Eclipse

Native JAR files and their respective base JAR files can be bundled in custom ways, e.g. eclipse Jar-In-Jar etc.

   Manual tested w/ Eclipse:
   
   Preparations:
   ===============
   
   1) Set up a vanilla eclipse (3.7.0) workspace
   
   2) Add the JOGL User Library:
     - Window.Preference
      - Java.Build_Path.User_Libraries:
        + JOGL
           + gluegen-rt.jar
           + jogl-all.jar
           + gluegen-rt-natives-linux-amd64.jar
           + jogl-all-natives-linux-amd64.jar
   
           You may add all other native JARs here.
           Note that these are not required in the CLASSPATH by JOGL,
           however, they are required by Eclipse to export your project as a Runnable JAR File.
   3) New test project
     -  Right-click your project in the Package Explorer and click "Properties".
          - Select "Java Build Path" and click the "Libraries" tab.
             + JOGL
     - Add some simple code ..
     - Run as Java Application ..
   
   Test-1:
   =========
   
   Export
     - Right-click your project in the Package Explorer and click "Export"
       - Select Java.Runnable_JAR_file
         + Launch configuration
         + some destination path
         + Library handling:
           Copy required libraries into a sub-folder next to the generated JAR
   
   Result: Works!
   
   ./lala01.jar
   ./lala01_lib/jogl-all.jar
   ./lala01_lib/jogl-all-natives-linux-amd64.jar
   ./lala01_lib/... etc ..
   
   Test-2:
   =========
   
   Export
     - Right-click your project in the Package Explorer and click "Export"
       - Select Java.Runnable_JAR_file
         + Launch configuration
         + some destination path
         + Library handling:
           Package required libraries into generated JAR
   Result: Works!
   
   ./lala02.jar:
     Manifest-Version: 1.0
     Rsrc-Class-Path: ./ gluegen-rt-natives-linux-amd64.jar gluegen-rt.jar
                         jogl-all-natives-linux-amd64.jar jogl-all.jar
     Class-Path: .
     Rsrc-Main-Class: Test01
     Main-Class: org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader