I am trying to bundle a java program for Mac users. I first found this article that explains how to do it with Ant, and then, I found this that seems perfect for Maven.
Here are step by step what I did to do it with a test project on Ubuntu 16.04.1 LTS
.
In your case steps 1 to 3 will be done on your GNU/Linux env and the last one on Mac OS X.
JRE
As you only need the JRE
, the easiest thing to do is:
tar.gz
version of the JRE
for Mac OS X
which is currently jre-8u112-macosx-x64.tar.gz
.${jre-folder}
(for example /foo/bar/jre1.8.0_112.jre
). My typical maven project structure:
TestProject └── src | └── main | └── java | └── my | └── pkg | └── MyClass.java └── pom.xml
My class my.pkg.MyClass
which actually does an arbitrary task. Here, it simply dumps the system properties into a temporary file, just to be able to easily check that it has been called:
package my.pkg;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class MyClass {
public static void main(String[] args) throws IOException {
Path path = Files.createTempFile("MyClass", "txt");
try (BufferedWriter writer = Files.newBufferedWriter(path)) {
System.getProperties()
.entrySet()
.stream()
.forEach(
entry -> {
try {
writer.write(entry.getKey() + "=" + entry.getValue() + "\n");
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
);
}
}
}
My pom
file:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>TestProject</groupId>
<artifactId>TestProject</artifactId>
<version>0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>sh.tak.appbundler</groupId>
<artifactId>appbundle-maven-plugin</artifactId>
<version>1.1.0</version>
<configuration>
<mainClass>my.pkg.MyClass</mainClass>
<!--
For example
<jrePath>/foo/bar/jre1.8.0_112.jre</jrePath>
-->
<jrePath>${jre-folder}</jrePath>
<generateDiskImageFile>true</generateDiskImageFile>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>bundle</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Simply launch the command mvn package appbundle:bundle
from the root of the directory TestProject
.
This will build the dmg file in the target
folder with the JRE
for Mac OS X
included, in this particular case it will be called TestProject-0.1-SNAPSHOT.dmg
.
On the target Mac OS X
:
TestProject.app
, you will see an icon appear and quickly disappear as the test program is rather shortcat $TMPDIR/MyClass*
from a terminal, you will then see the content of the temporary file that has been created by the test application.To add resources to the generated dmg file, you can use additionalResources
with a fileSet
.
<plugin>
<groupId>sh.tak.appbundler</groupId>
<artifactId>appbundle-maven-plugin</artifactId>
<version>1.1.0</version>
<configuration>
...
<additionalResources>
<fileSet>
<directory>/path/to/my/resources/folder</directory>
<includes>
<include>*.pdf</include>
</includes>
</fileSet>
</additionalResources>
</configuration>
...
</plugin>
This example will add all the pdf
files from /path/to/my/resources/folder
into the generated dmg file.
To add resources to the generated app file, you can use additionalResources
with a fileSet
.
<plugin>
<groupId>sh.tak.appbundler</groupId>
<artifactId>appbundle-maven-plugin</artifactId>
<version>1.1.0</version>
<configuration>
...
<additionalBundledClasspathResources>
<fileSet>
<directory>/path/to/my/resources/folder</directory>
<includes>
<include>*.pdf</include>
</includes>
</fileSet>
</additionalBundledClasspathResources>
</configuration>
...
</plugin>
This example will add all the pdf
files from /path/to/my/resources/folder
to the generated app file into /Contents/Java/lib
, they will be automatically included to the classpath of your application such that you will be able to access them easily.