Preparation
The Laying out your project files for a Maven build page describes the overall layout of a maven project.
Compiling Using Maven
To compile izpack IzPack using Maven, use the izpack-maven-plugin. There is good documentation at the izpack-maven-plugin page, but this page will describe how to use the most recent izpack IzPack plugin (5.0.0-beta9 at the time of this writing).
I'll assume you have some custom izpack panels, but if you don't, you can omit some of the steps that we go over here:
Using Custom Panels
If you have custom panels, you'll want to put them in their own Maven module. This module should be a standard Maven project, but you should include izpack as a provided dependency:
<dependencies>
<dependency>
<groupId>org.codehaus.izpack</groupId>
<artifactId>izpack-compiler</artifactId>
<version>${izpack.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
We use scope = provided because we only need Maven to use the izpack dependency at compile time. In this project, you can create your custom IzPack panels. Be sure that the Java package names that contain your custom IzPack panels begin with "com", "net", or "org", or else they will not be able to be loaded by your IzPack installer.
Creating the IzPack Installer Module
Now, create a separate Maven module that will produce your izpack installer.
The basic strategy we'll use is this:
- We'll configure our Maven pom to create a "staging" area that will contain our izpack descriptor and all of our installer resources, including the jars that we want to package in our installer.
- We will use the Maven
maven-antrun-plugin
to copy our izpack descriptor file and resources into this "staging" area. - We'll use the
maven-dependency-plugin
to copy the jar with our custom panels, and any other jar dependencies that we want in our installer. We'll configure two different "executions" of themaven-dependency-plugin
; we'll have this plugin copy our application jars into one location, and the custom panel jars into a separate location.
- We will use the Maven
- We'll then configure the
izpack-maven-plugin
to point it to our staging area and our installer descriptor.
Create Some Helpful Properties
<properties>
<izpack.version>5.0.0-beta9</izpack.version>
<izpack.staging>${project.build.directory}/staging</izpack.staging>
</properties>
Notes:
${project.build.directory}
typically references the compilation ./target/ directory of your module- Properties from your Maven project compiling the IzPack project can be directly references in the install.xml using the property name enclosed in '@{' and '}' , for example:
<jar src=
"@{app.stage.dir}/lib/appcore.jar"
/>
This applies just on properties defined in the calling project, not for properties seen in the calling project.
Add Your Dependencies
We'll want to add at least two dependencies–one will be the dependency that contains your custom panel, the other(s) will be the dependency that contains your actual Java application. My dependencies look like this:
...
.
Custom IzPack panels are supported and are discussed in the "Using Custom Panels" section.
Creating the Maven installer project for IzPack
Create a separate Maven project that will produce your izPack installer. You can refer to the IzPack Maven Plugin Reference section for details on the plug-in and the meaning of the configuration settings.
The basic strategy is as follows:
- Configure the Maven pom to create a "staging" area that will contain our izPack descriptor and all of our installer resources, including the jars that we want to include in our installer.
- Use the Maven
maven-antrun-plugin
to copy our izPack descriptor file and resources into this "staging" area. - Use the
maven-dependency-plugin
to copy the jar with our custom panels, and any other jar dependencies that we want in our installer. Two different "executions" of themaven-dependency-plugin may be required
; one to copy our application jars into one location, and if there are custom panels, another to copy the custom panel jars into a separate location.
- Use the Maven
- We'll then configure the
izpack-maven-plugin
to point it to our staging area and our installer descriptor.
Create Some Helpful Properties
pom
, so let's configure it as a <property>
to make things clearer. Also configure the izPack version.pom
file:Code Block | ||||
---|---|---|---|---|
| ||||
<properties>
<izpack.version>5.0.9</izpack.version>
<izpack.staging>${project.build.directory}/staging</izpack.staging>
</properties> |
Notes:
${project.build.directory}
references the compilation ./target/ directory of your module- Properties from your Maven project can be directly references in the install.xml using the property name enclosed in '@{' and '}' , for example:
<jar src=
"@{izpack.staging
}/lib/appcore.jar"
/>
This only applies to properties defined in the compiling project.
Add Your Dependencies
- Add the dependency that contains your actual Java application to be installed.
- If custom panels are used, add the dependency that contains your custom panel,
Code Block | ||||
---|---|---|---|---|
| ||||
<dependencies> <dependency> <groupId>com.mycompany</groupId> |
...
<artifactId>myapplication</artifactId> |
...
<version>1.0-SNAPSHOT</version> |
...
</dependency> |
...
<dependency> <groupId>com.mycompany</groupId> <artifactId>myapplication-utilities</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>com.mycompany</groupId> |
...
<artifactId>mycustompanels</artifactId> |
...
<version>1.0-SNAPSHOT</version> |
...
</dependency> |
...
</dependencies> |
Configure the maventhe maven-antrun-plugin
We'll use Use the maven-antrun-plugin
to copy our the installer descriptor and installer resources (images, text files, etc.) into our the "staging" area.
Put your the installer descriptor and resources underneath src/izpack
in your module. In your the pom's <build>
section, configure configure the maven-antrun-plugin
to copy this entire directory to our the staging area:
...
Code Block | ||||
---|---|---|---|---|
| ||||
<plugin> |
...
<artifactId>maven-antrun-plugin</artifactId> |
...
<executions> |
...
<execution> |
...
<id>create-staging-area</id> |
...
<phase>process-resources</phase> |
...
<goals> |
...
<goal>run</goal> |
...
</goals> |
...
<configuration> |
...
<tasks> |
...
<copy todir="${izpack.staging}"> |
...
<fileset dir="${basedir}/src/izpack"/> |
...
</copy> |
...
</tasks> |
...
</configuration> |
...
</execution> |
...
</executions> |
...
</plugin> |
Configure the maventhe maven-dependency-plugin
We'll configure Configure the maven-depenency-plugin
to copy both our the application jars and the jar with our custom panel. Here's how it looks ('s jars.
If there are custom panels, copy its jar as well.
Example with custom panels (see the inline XML comments for more details):
...
Code Block | ||||
---|---|---|---|---|
| ||||
<plugin> |
...
<artifactId>maven-dependency-plugin</artifactId> |
...
<configuration> <excludeTransitive>false</excludeTransitive> |
...
<!-- reference our custom panels jar in our installer descriptor without its version --> <stripVersion>true</stripVersion> <overWriteReleases>true</overWriteReleases> <overWriteSnapshots>true</overWriteSnapshots> |
...
|
...
|
...
<overWriteIfNewer>true</overWriteIfNewer> </configuration> <executions> <execution> <!-- copy *application* jars to izpack staging lib |
...
- |
...
- |
...
> |
...
<id>copy-product-dependencies</id> <phase>prepare-package</phase> |
...
<goals> <goal>copy-dependencies</goal> |
...
</goals> <configuration> |
...
<outputDirectory>${izpack.staging}/lib</outputDirectory> <excludeScope>system</excludeScope> |
...
<!-- this excludes tools.jar, e.g. --> <excludeArtifactIds>mycustompanels</excludeArtifactIds> |
...
<!-- IMPORTANT: don't copy custom panels where our application jars live --> |
...
<excludeGroupIds>org.codehaus.izpack</excludeGroupIds> <!-- IMPORTANT: we don't want to copy the IzPack dependency where our application jars |
...
live --> </configuration> </execution> <execution> |
...
<!-- copy izpack custom (custom panels, etc.) jars to izpack staging custom --> |
...
<id>copy-izpack-dependencies</id> <phase>prepare-package</phase> <goals> |
...
<goal>copy-dependencies</goal> </goals> <configuration> |
...
<outputDirectory>${izpack.staging}/custom</outputDirectory> |
...
<includeArtifactIds>mycustompanels</includeArtifactIds> |
...
<!-- IMPORTANT: this |
...
causes *only* our custom panels to be copied --> </configuration> </execution> |
...
</executions>
</plugin> |
Some key points:
- The first
execution
section configures the copying of our application jars to thelib/
directory under our staging directory (i.e.,target/staging/lib
). Note that we have to explicitly exclude the IzPack dependency as well as any custom panels dependency. We don't need these showing up in our installed application! - The second
execution
section configures the copying of our custom panels jar to thecustom/
directory under our staging directory (i.e.,target/staging/custom
). Note that we explicitly include our custom panels dependency so that no other jars are copied tocustom/
. It wouldn't hurt anything if this happened, but why do unnecessary work?
maven-dependency-plugin
is very configurable. You may need to customize some of this configuration for your own purposes.Configure the izpack-maven-plugin
- Add the base directory to the
izpack-maven-plugin.
This is our staging area. - Add the location of the install file.
Code Block | ||||
---|---|---|---|---|
| ||||
<plugin> <groupId>org.codehaus.izpack</groupId> <artifactId>izpack-maven-plugin</artifactId> <version>${izpack.version}</version> <executions> <execution> |
...
<phase>package</phase> |
...
<goals><goal>izpack</goal></goals> |
...
<configuration> <!-- |
...
base |
...
for |
...
relative |
...
paths in izpack |
...
descriptor |
...
--> |
...
|
...
<baseDir>${izpack.staging}</baseDir> |
...
<installFile>${basedir}/src/izpack/install.xml</installFile> </configuration> |
...
</execution> </executions> <dependencies> <dependency> |
...
|
...
<groupId>org.codehaus.izpack</groupId> <artifactId>izpack-panel</artifactId> |
...
|
...
<version>${izpack. |
...
version}</ |
...
version> </dependency> |
...
. . |
...
. |
...
</dependencies>
</plugin> |
Create Your Installer Descriptor
Your installer descriptor should reference resources and jars relative to the staging area. For example, here is a resources section in our installer descriptor (i.e., install.xml):
Code Block | ||||
---|---|---|---|---|
| ||||
<resources> |
...
<res src="@{izpack.staging}/common_resources/img/install-sidebar.png" id="Installer.image"/> <res src="hello.html" id="HTMLHelloPanel.info"/> <res src="license.html" |
...
id="HTMLLicencePanel.licence"/>
</resources> |
Note: these resources are originally under src/izpack
. They are copied from this directory to the staging area, where the IzPack compiler will look for them.
Summary
When finished, the entire build section of our pom should look something like this:
Code Block | ||||
---|---|---|---|---|
| ||||
. . . <build> <plugins> <!-- |
...
copy |
...
izpack |
...
resources |
...
into |
...
izpack |
...
staging |
...
area, |
...
expected |
...
by |
...
izpack.xml --> |
...
<plugin> <artifactId>maven-antrun-plugin</artifactId> <executions> |
...
<execution> |
...
<id>create-staging-area</id> |
...
Some key points:
- The first
execution
section configures copying our application jars to thelib/
directory under our staging directory (i.e.,target/staging/lib
). Note that we have to explicitly exclude the izpack dependency as well as our custom panels dependency. We don't need these showing up in our installed application! - The second
execution
section configures copying our custom panels jar to thecustom/
directory under our staging directory (i.e.,target/staging/custom
). Note that we explicitly include our custom panels dependency so that no other jars are copied tocustom/
. It wouldn't hurt anything if this happened, but why do unnecessary work?
maven-dependency-plugin
is very configurable. You may need to customize some of this configuration for your own purposes.Configure the izpack-maven-plugin
We need to tell the izpack-maven-plugin
what to use as the base directory (this is our staging area), and also tell it the install file to use:
<plugin>
<groupId>org.codehaus.izpack</groupId>
<artifactId>izpack-maven-plugin</artifactId>
<version>${izpack.version}</version>
...
<phase>process-resources</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <copy todir="${izpack.staging}"> <fileset dir="${basedir}/src/izpack"/> </copy> </tasks> </configuration> </execution> </executions> </plugin> <plugin> <artifactId>maven-dependency-plugin</artifactId> <configuration> |
...
<excludeTransitive>false</excludeTransitive> |
...
<stripVersion>true</stripVersion> <overWriteReleases>true</overWriteReleases> |
...
|
...
|
...
|
...
|
...
|
...
<overWriteSnapshots>true</overWriteSnapshots> |
...
|
...
|
...
<overWriteIfNewer>true</overWriteIfNewer> |
...
<excludeScope>system</excludeScope> |
...
</configuration> <executions> |
...
|
...
<execution> |
...
|
...
|
...
<!-- copy product jars to izpack staging lib --> |
...
<id>copy- |
...
product-dependencies</id> |
...
<phase>prepare-package</phase> |
...
<goals> |
...
|
...
<goal>copy-dependencies</goal> |
...
</goals> <configuration> |
...
...
|
...
Some key points:
- Even though you've already declared your custom panels dependency as a project dependency, you'll also need to declare it as a dependency to the izpack plugin itself, or else you will see classloading errors. (This is because Maven gives every plugin execution its own classloader, which cannot see the classpath of the project itself.)
Create Your Installer Descriptor
Your installer descriptor should reference resources and jars relative to the staging area. For example, here is a resources section in our installer descriptor (i.e., install.xml):
<resources>
<res src="img/install-sidebar.png" id="Installer.image"/>
<res src="hello.html" id="HTMLHelloPanel.info"/>
<res src="license.html" id="HTMLLicencePanel.licence"/>
</resources>
Note that these resources are originally under src/izpack
. They are copied from this directory to the staging area, where the izpack compiler will look for them.
Also, don't forget to tell the izpack compiler about your custom panels jar. In your install.xml
file:
<jar src="custom/mycustompanels.jar"/>
Info | ||
---|---|---|
| ||
You should see now why we use the |
Here's an example of referencing a custom panel. Again, in our installer descriptor:
<panels>
<panel classname="com.mycompany.izpack.panel.MyHelloPanel"/>
</panels>
Note that we use the fully qualified name of the panel class.
Summary
When finished, the entire build section of our pom should look something like this:
...
<outputDirectory>${izpack.staging}/lib</outputDirectory>
<excludeScope>system</excludeScope>
<!-- this excludes tools.jar, e.g. -->
<excludeArtifactIds>mycustompanels</excludeArtifactIds>
<excludeGroupIds>org.codehaus.izpack</excludeGroupIds>
</configuration>
</execution>
<execution>
<!-- copy izpack custom (custom panels, etc.) jars to izpack staging custom -->
<id>copy-izpack-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${izpack.staging}/custom</outputDirectory>
<includeArtifactIds>mycustompanels</includeArtifactIds>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.izpack</groupId>
<artifactId>izpack-maven-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>izpack</goal>
</goals>
<configuration>
<!-- base for relative paths in izpack descriptor -->
<baseDir>${izpack.staging}</baseDir>
<installFile>${basedir}/src/izpack/install.xml</installFile>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.codehaus.izpack</groupId>
<artifactId>izpack-panel</artifactId>
<version>${izpack.version}</version>
</dependency>
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>mycustompanels</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
.
.
.
|
As mentioned at the start of this article, the dependencies of your application are project dependencies and need to be specified as normal Maven dependencies in the project's dependencies section.
Code Block | ||||
---|---|---|---|---|
| ||||
.
.
.
</build>
<dependencies>
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>myapplication</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>mycustompanels</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project> |
Using Custom Panels
If you have custom panels, they should be developed in a separate Maven project. This is a standard Maven project, but you should include izPack as a provided dependency:
Code Block | ||||
---|---|---|---|---|
| ||||
<dependencies>
<dependency>
<groupId>org.codehaus.izpack</groupId>
<artifactId>izpack-compiler</artifactId>
<version>${izpack.version}</version>
<scope>provided</scope>
</dependency>
</dependencies> |
We use scope = provided because we only need Maven to use the IzPack dependency at compile time.
In this project, you can create your custom IzPack panels.
maven-dependency-plugin
to copy the custom panel jar to the staging area.This example include a section for custom panels which may be omitted if it does not apply.
Code Block | ||||
---|---|---|---|---|
| ||||
<plugin>
<groupId>org.codehaus.izpack</groupId>
<artifactId>izpack-maven-plugin</artifactId>
<version>${izpack.version}</version>
<executions>
<execution>
<phase>package</phase>
<goals><goal>izpack</goal></goals>
<configuration>
<!-- base for relative paths in izpack descriptor -->
<baseDir>${izpack.staging}</baseDir>
<installFile>${basedir}/src/izpack/install.xml</installFile>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.codehaus.izpack</groupId>
<artifactId>izpack-panel</artifactId>
<version>${izpack.version}</version>
</dependency>
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>mycustompanels</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</plugin> |
Some key points:
- Even though the custom panels dependency is declared as a project dependency, it also must be declared as a dependency to the IzPack plugin itself, or else you will see classloading errors. Maven gives every plugin execution its own classloader, which cannot see the classpath of the project itself.
Add the <execution> section
- Add the second
execution
section to copying of the custom panels jar to thecustom/
directory under our staging directory (i.e.,target/staging/custom
). Note that we explicitly include our custom panels dependency so that no other jars are copied tocustom/
. It wouldn't hurt anything if this happened, but why do unnecessary work.
Summary
When finished, the entire build section of the pom should look something like this:
Code Block | ||||
---|---|---|---|---|
| ||||
<?xml version="1.0"?> . . . <build> <plugins> <!-- copy IzPack resources into IzPack staging area, expected by izpack.xml --> <plugin> <artifactId>maven-antrun-plugin</artifactId> <executions> <execution> <id>create-staging-area</id> |
...
<phase>process-resources</phase> <goals> |
...
<goal>run</goal> </ |
...
goals> <configuration> |
...
|
...
<tasks> |
...
|
...
|
...
<copy todir="${izpack.staging}"> |
...
|
...
|
...
<fileset dir="${basedir}/src/izpack"/> |
...
|
...
< |
...
/copy> |
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
</tasks> |
...
</configuration> </execution> |
...
</executions> </plugin> <plugin> <artifactId>maven-dependency-plugin</artifactId> |
...
<configuration> <excludeTransitive>false</excludeTransitive> |
...
<stripVersion>true</stripVersion> |
...
<overWriteReleases>true</overWriteReleases> |
...
<overWriteSnapshots>true</overWriteSnapshots> <overWriteIfNewer>true</overWriteIfNewer> |
...
<excludeScope>system</excludeScope> </configuration> <executions> |
...
<execution> <!-- copy product jars to |
...
izpack staging lib --> |
...
<id>copy-product-dependencies</id> |
...
<phase>prepare-package</phase> <goals> |
...
<goal>copy-dependencies</goal> </goals> |
...
<configuration> <outputDirectory>${izpack.staging}/lib</outputDirectory> |
...
<excludeScope>system</excludeScope> |
...
<!-- this excludes tools.jar, e.g. -- |
...
> |
...
<excludeArtifactIds>mycustompanels</excludeArtifactIds> |
...
|
...
<excludeGroupIds>org.codehaus.izpack</excludeGroupIds> |
...
|
...
</configuration> |
...
</execution> |
...
<execution> <!-- copy izpack custom (custom panels, etc.) jars to izpack staging custom --> |
...
|
...
<id>copy-izpack-dependencies</id> |
...
|
...
<phase>prepare-package</phase> |
...
<goals> |
...
<goal>copy-dependencies</goal> |
...
</goals> <configuration> |
...
<outputDirectory>${izpack.staging}/custom</outputDirectory> <includeArtifactIds>mycustompanels</includeArtifactIds> |
...
</configuration> |
...
</execution> </executions> </plugin> <plugin> |
...
<groupId>org.codehaus.izpack</groupId> <artifactId>izpack-maven-plugin</artifactId> <executions> |
...
<execution> |
...
<phase>package</ |
...
phase> <goals> |
...
<goal>izpack</goal> |
...
</goals> <configuration> |
...
<!-- base for relative paths in izpack descriptor --> |
...
|
...
<baseDir>${izpack.staging}</ |
...
baseDir> |
...
|
...
|
...
|
...
<installFile>${basedir}/src/izpack/install.xml</installFile> |
...
|
...
|
...
</configuration> |
...
</execution> |
...
</executions> |
...
<dependencies> |
...
<dependency> |
...
<groupId>org.codehaus.izpack</groupId> <artifactId>izpack-panel</artifactId> |
...
<version>${izpack. |
...
version}</ |
...
version> </dependency> |
...
<dependency> |
...
<groupId>com.mycompany</groupId> |
...
|
...
<artifactId>mycustompanels</artifactId> |
...
|
...
<version>1.0</version> </dependency> |
...
</dependencies> </plugin> </plugins> |
...
Troubleshooting
...
</build> |
Add the custom panel jar to the installer description
Also, don't forget to tell the IzPack compiler about your custom panels jar in the <resources>
element in your install.xml
file:
<jar src="custom/mycustompanels.jar"/>
Info | ||
---|---|---|
| ||
You should see now why we use the |
Add custom panel to the list of panels
Here's an example of referencing a custom panel. Again, in our installer descriptor:
Code Block | ||||
---|---|---|---|---|
| ||||
<panels>
<panel classname="com.mycompany.izpack.panel.MyHelloPanel"/>
<panel ......../>
<panel ......../>
</panels> |
Note that we use the fully qualified name of the panel class.
Troubleshooting
There are a few simple things to check if your installer is not created properly.
- Read the Maven logs to be sure that no errors are reported.
- Check the staging area to make sure that it contains all of the assets that you expected.
- Check the install.xml file to be sure that all panels are included and that all of the pack descriptions are correct.
- Check that all of the referenced specification files exist with the correct names and have the correct contents.
- Watch for case sensitivity if this applies to the environment.
References
[1] http://izpack.codehaus.org/izpack-maven-plugin/
...