I had the following requirements:
- create an installer for my application;
- the
application is based on web-technologies, so the installer must ship an
application server and automatically install my webapp into it;
- the application requires a dbms (Postgres was the
choice, a similar process will work also with Hsqldb), so the installer
must ship it, possibly automatically installing it on the target
machine;
- my application is build through maven, so the creation of the installer should be integrated in the whole build chain;
- the installer must be easy to use, even for monkey-brained users
I looked for a standardized way to do all this: although Maven team has planned some native support for this kind of problems see this,
at the moment there are only partial solutions from non-mainstream
external plugins. I‘ll go through the entire process, and at the end,
some more alternatives are proposed.
The solution I ended up involves the following steps:
- install Postgres installer into a maven repository:
this is an easy step, because it only requires to zip the target file
(i did it manually, but if you really you can let maven do it
for you...which I don‘t suggest at all), and install and deploy it into
your local repository. So I downloaded the file from the msi postgres windows and issued this:
mvn -Dfile=postgres-installer.zip \n -DgeneratePom=true \n -DgroupId=postgres \n -DartifactId=postgres-installer \n -Dversion=VERSION-NUMBER -DrepositoryId=SERVER \n -Durl=scp://path/to/your/maven2/repository \n -Dpackaging=zip \n deploy:deploy-file
- install an application server into a maven repository: do the
same for your application server of choice: mine was jetty, because I
use it heavily during development, and because its installint procedure
is a matter of unzipping and copying its files somewhere (which other
application servers allow this ?):
mvn -Dfile=jetty-6.0.2.zip \n -DgeneratePom=true \n -DgroupId=jetty \n -DartifactId=jetty \n -Dversion=VERSION-NUMBER -DrepositoryId=SERVER \n -Durl=scp://path/to/your/maven2/repository \n -Dpackaging=zip \n deploy:deploy-file
- install the application war into a maven repository: this is
maybe the easiest step: given your webapp, which should have a
packaging element of value war, it is only a matter
of doing a mvn deploy from the root of your project, given that you‘ve
provided the correct distribution management informations in the pom; i
won‘t comment further on this;
- install locally the izpack-maven-plugin: this mojo is still
a proposal, so you can‘t simply declare it in your pom: you need to
install by your self. Let‘s get it from Jira and from the root directory:
mvn install
- use the maven-dependency-plugin properly:this is the
interesting part. It requires just a little bit of knowledge of the
goals available through this plugin and to combine them propertly. here
is the result:
<plugins> <plugin> <groupId>org.codehaus.mojo</groupId>
<artifactId>dependency-maven-plugin</artifactId> <executions> <!-- unzip jetty & postgresql --> <execution> <id>unzip-jetty-postgresql</id>
<phase>process-resources</phase> <goals> <goal>unpack</goal> </goals> <configuration>
<artifactItems> <artifactItem> <groupId>jetty</groupId> <artifactId>jetty-standalone</artifactId> <version>6.0.2</version>
<type>zip</type> <outputDirectory> ${project.build.directory}/${project.build.finalName}/ </outputDirectory> </artifactItem> <artifactItem>
<groupId>postgresql</groupId> <artifactId>postgresql-installer-win</artifactId> <version>8.1.5</version> <type>zip</type>
<outputDirectory> ${project.build.directory}/${project.build.finalName}/postgresql/ </outputDirectory> </artifactItem> </artifactItems> </configuration> </execution>
<execution> <id>copy-webapp-war</id> <phase>process-resources</phase> <goals>
<goal>copy</goal> </goals> <configuration> <stripVersion>true</stripVersion> <artifactItems>
<artifactItem> <groupId>your-groupid</groupId> <artifactId>your-webapp</artifactId> <version>1.0-SNAPSHOT</version>
<type>war</type> <outputDirectory> ${project.build.directory}/${project.build.finalName}/jetty-6.0.2/webapps/ </outputDirectory> </artifactItem>
</artifactItems> </configuration> </execution> </executions> </plugin> </plugins>
- configure the izpack plugin to run in the package phase: this is very easy, and goes like this:
<plugin>
<groupId>org.codehaus.mojo</groupId> <artifactId>izpack-maven-plugin</artifactId> <version>1.0-SNAPSHOT</version> <executions>
<execution> <phase>package</phase> <goals> <goal>izpack</goal> </goals>
</execution> </executions> </plugin>
Having this pom configuration, it is enough to issue mvn package to find in our target/
directory a beautiful executable jar file, which will install our
application, togheter with postgres and application in the target
machine.
Ah, sure: you need a working izpack.xml file in src/izpack/
directory to let the maven plugin works correctly. In a future blog
entry, I‘ll go on with this example showing how to write such file.
One more thing: very recently, Vincent Massol proposed a new support
(the Packager API) within the core api of cargo plugin, which should
greetly simplify this process. Stay tuned!
|