The 10 minutes AntInstaller and maven guide

The information about the combination of these two goodies is to say the least scarce. I decided to create a minimal small POC project which

Full credit to Ittai who helped me out with this post.


1-Has a self contained Maven POM, which works out of the box without any major modifications.
2-Explicitly invokes AntInstaller via a configuration file while utilizing an antinstaller properties file
3-Is easy to understand and expand.

Without further ado, I shall describe the files involved in the project which was fully build using the one and only Intellij IDEA.

Folder structure is as follows:

|-tikalk-installer
 |---src
 |-----main
 |-------antlib
 |-------installer
 |-------lib

The directory structure was generated using the folowing linux command:

ls -R | grep ":$" | sed -e 's/:$//' -e 's/[^-][^\/]*\//--/g' \
-e 's/^/ /' -e 's/-/|/'



The root directory contains the maven POM:

<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/maven-v4_0_0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.tikalk.tikalk.runtime.prod</groupId>
    <artifactId>tikalk-installer</artifactId>
    <version>1.0-SNAPSHOT</version>
    <name>Rt installer</name>
    <packaging>pom</packaging>
    <inceptionYear>2010</inceptionYear>

    <developers>
        <developer>
            <name>Shlomo</name>
            <organization>Tikalk</organization>
        </developer>
    </developers>

    <pluginRepositories>
        <pluginRepository>
            <id>nexus -public</id>
            <url>http://build/nexus/content/groups/public</url>
        </pluginRepository>
    </pluginRepositories>

    <repositories>
        <repository>
            <id>nexus -public</id>
            <url>http://build/nexus/content/groups/public</url>
        </repository>

    </repositories>

    <properties>       
        <jdk.product.version>java-6-sun</jdk.product.version>
        <jdk.product.name>jdk</jdk.product.name>       
        <rt.base.folder>target</rt.base.folder>
    </properties>

    <dependencies>
        <!-- Ant-Contrib for Special Ant Tasks (IF) -->
        <dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-artifact-ant</artifactId>
            <version>2.0.4</version>
        </dependency>
        <dependency>
            <groupId>org.apache.ant</groupId>
            <artifactId>ant</artifactId>
            <version>1.7.0</version>
        </dependency>
        <dependency>
            <groupId>ant-contrib</groupId>
            <artifactId>ant-contrib</artifactId>
            <version>1.0b2</version>
            <exclusions>
                <exclusion>
                    <groupId>ant</groupId>
                    <artifactId>ant</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>ant</groupId>
            <artifactId>optional</artifactId>
            <version>1.5.4</version>
        </dependency>
        <dependency>
            <groupId>ant</groupId>
            <artifactId>ant-antlr</artifactId>
            <version>1.6.5</version>
        </dependency>
        <dependency>
            <groupId>antlr</groupId>
            <artifactId>antlrall</artifactId>
            <version>2.7.4</version>
        </dependency>

        <dependency>
            <groupId>ant</groupId>
            <artifactId>ant-nodeps</artifactId>
            <version>1.6.5</version>
        </dependency>

        <dependency>
            <groupId>ant-installer</groupId>
            <artifactId>ant-installer</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
            <groupId>ant-installer-ext</groupId>
            <artifactId>ant-installer-ext</artifactId>
            <version>1.0</version>
        </dependency>
    </dependencies>
    <profiles>
        <profile>
            <id>new-installer</id>
            <properties>
                <platform>linux</platform>
            </properties>
            <activation>
                <activeByDefault>true</activeByDefault>
                <os>
                    <family>linux</family>
                </os>
            </activation>

            <build>
                <plugins>
                    <plugin>
                        <groupId>org.jvnet.maven-antrun-extended-plugin</groupId>
                        <artifactId>maven-antrun-extended-plugin</artifactId>
                        <version>1.8</version>
                        <dependencies>
                            <dependency>
                                <groupId>ant-installer</groupId>
                                <artifactId>ant-installer</artifactId>
                                <version>1.0</version>
                            </dependency>
                            <dependency>
                                <groupId>ant-installer-ext</groupId>
                                <artifactId>ant-installer-ext</artifactId>
                                <version>1.0</version>
                            </dependency>
                        </dependencies>
                        <executions>
                            <execution>
                                <id>initialize</id>
                                <phase>initialize</phase>
                                <configuration>
                                  <tasks>
                                     <copy file="src/main/installer/ant.install.properties"
                                              tofile="src/main/target/ant.install.properties"
                                              overwrite="true" verbose="true"/>

                                      <resolveArtifact artifactId="jdk" property="jdk.archive"/>                                    

                                      <taskdef name="installer"
                                                 classname="org.tp23.antinstaller.taskdefs.Installer"
                                                 classpathref="maven.plugin.classpath"/>

                                        <!-- configure the installer task -->
                                        <installer file="src/main/target/tikalk-installer.jar"
                                                   compress="true"
                                                   extractType="SelfExtractor"
                                                   installConfig="src/main/installer/antinstall-config.xml"
                                                   buildFile="src/main/installer/build.xml"
                                                   antInstallLib="src/main/lib"
                                                   antLib="src/main/antlib"
                                                   validateConfig="true"
                                                   failOnError="true" >

                                            <fileset file="${jdk.archive}" />                                           

                                        </installer>

                                  </tasks>

                                </configuration>
                                <goals>
                                    <goal>run</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>


                </plugins>
            </build>

        </profile>

    </profiles>
</project>

 

Let us try and understand the various sections of the maven POM. The installer is minimal and will pack a JDK inside it, it can be any other artifact(s) such as mysql or your own artifact placed under a private Nexus repository.

 

The most cruical section is the one starting at line 114.  It defines the plug-in taht allows maven to interact with Ant and Antinstaller. Additionally, it defines two dependencies, which MUST be placed under your local nexus repo so that they can be resolved.

 

 <plugin>
                        <groupId>org.jvnet.maven-antrun-extended-plugin</groupId>
                        <artifactId>maven-antrun-extended-plugin</artifactId>
                        <version>1.8</version>
                        <dependencies>
                            <dependency>
                                <groupId>ant-installer</groupId>
                                <artifactId>ant-installer</artifactId>
                                <version>1.0</version>
                            </dependency>
                            <dependency>
                                <groupId>ant-installer-ext</groupId>
                                <artifactId>ant-installer-ext</artifactId>
                                <version>1.0</version>
                            </dependency>
                        </dependencies>

Next at line 135, we copy our own version of the property file used by the installer at runtime:

 <copy file="src/main/installer/ant.install.properties"
                                              tofile="src/main/target/ant.install.properties"
                                              overwrite="true" verbose="true"/>

 

Next at line 139 we define our only artifact that must be resolved (the jdk) at build time:

<resolveArtifact artifactId="jdk" property="jdk.archive"/> 

 

Next at line 142 we define the actual antinatller task:

  <taskdef name="installer"
                                                 classname="org.tp23.antinstaller.taskdefs.Installer"
                                                 classpathref="maven.plugin.classpath"/>

Note that the class loader will look under the  "maven.plugin.classpath" to try and locat the installer task.

 

Next at lines 146 to 156 the resulting installer is defined:

 

 <!-- configure the installer task -->
                                        <installer file="src/main/target/tikalk-installer.jar"
                                                   compress="true"
                                                   extractType="SelfExtractor"
                                                   installConfig="src/main/installer/antinstall-config.xml"
                                                   buildFile="src/main/installer/build.xml"
                                                   antInstallLib="src/main/lib"
                                                   antLib="src/main/antlib"
                                                   validateConfig="true"
                                                   failOnError="true" >
                                            <fileset file="${jdk.archive}" />          

Line 146 names the installer, e.g

tikalk-installer.jar

Line 149 referes to our own antinstall-config.xml file:

 installConfig="src/main/installer/antinstall-config.xml"

Line 150 referes to our own ant build.xml file:

 buildFile="src/main/installer/build.xml"

Last but not least, we include out only artifact inside the installer:

<fileset file="${jdk.archive}" />       

Under /src/main:
The installer directory contains:
A. The ant build.xml file used for invoking your actual installation tasks once the installer has been built and is run on a machine:

<?xml version="1.0"?>
<project name="Tikal installer build" default="" basedir="${basedir}">
    <target name="default" depends="">
        <echo>"Default"</echo>
    </target>
    <target name="configureServer-linux" depends="">
        <echo>server-linux</echo>
    </target>
</project>


B. The antinstall-config.xml file used for defining the installation tasks and gathering input from the user via a GUI or the command line:

(credit: http://wiki.eclipse.org/Migrate_the_ConfigureAperi_code_to_AntInstaller)

<?xml version="1.0"?>
<!DOCTYPE installer PUBLIC "-//tp23 //DTD Ant Installer Config//EN" "http://antinstaller.sf.net/dtd/antinstall-config-0.8.dtd">

<installer
        ui="swing,text,text-auto"
        verbose="true"
        debug="true"
        lookAndFeel="native"
        name="Tikalk  Installer"
        minJavaVersion="1.5"
        finishButtonText="Install"
        version="5.3"
        loadDefaults="true"
        wide="600:275">    
    <page
        type="input"
        name="intro"
        displayText="Welcome">
        <comment
            displayText=""
            explanatoryText="Tikalk Tikalk installer"
            />
        <comment displayText=""/>
        <comment displayText="Installer made with"/>
        <comment displayText="http://antinstaller.sourceforge.net" bold="true"/>
 		<hidden
 			property="env.HOSTNAME"
 			value="${env.COMPUTERNAME}"
 		/>
    </page>    
    <page
        type="input"
        name="componentSelection"
        displayText="Component Selection">
        <comment
        	displayText="The Tikalk system consists of two major components:
        	Server,Client"
				title="false" />
        <comment
        	displayText="You can configure any or all of these to run on this computer."
				title="false" />	
        <target
        	target="configureServer"
        	displayText="Server"
        	defaultValue="true"
        	osSpecific="true"
        	strict="false" />
    </page>
    <page
      	type="input"
    	name="installLocation"
    	displayText="Installation location" >
    	<directory
    		displayText="Installation location"
    		checkExists="true"
    		create="true"
    		defaultValue="/opt/Tikalk"
    		property="install.dir" />
    </page>
	<page 
		name="serverConfig"
		displayText="Server configuration"
		type="input"
		ifProperty="(${configureAgent}==true)OR(${configureServer}==true)">
		<comment
			displayText="Enter values to configure the server."
			title="true" />
		<validated
			property="server.hostname"
			displayText="Server hostname"
			defaultValue="${env.HOSTNAME}"
			regex="[a-zA-Z0-9.]*"
		/>
	</page>
    <page
			type="progress"
			name="progress"
			showTargets="true"
			displayText="Installation progress" >
	</page>	
</installer>


C. The ant.install.properties used for defining default installation values:

### Ant Installer - properties auto generated on Mon\ Oct\ 25\ 07\:55\:40\ GMT\ 2010

basedir = /home/dambo/projects/tikalk-installer/src/main/target/.
ant.install.config.version = 5.3


## Properties from Page:intro
# .HiddenPropertyInput
env.HOSTNAME = 

## Properties from Page:componentSelection
# .TargetInput
configureServer = true
# Targets selected for page
componentSelection-targets = configureServer-linux,

## Properties from Page:installLocation
# .DirectoryInput
install.dir = /home/dambo/tikalk-installer

## Properties from Page:serverConfig
# .ValidatedTextInput
server.hostname = localhost

## Properties from Page:progress

 

 

The lib directory contains ant lib libraries (ships with ant installer)

 

The antlib directory contains additional "antlib" third party libraries (ships with antinstaller)
 
Once the maven target "install" is invoked, a file named tikalk-installer.jar will be generated. In order to actuayly run teh installer use:

 

 java -jar tikalk-installer.jar

 

Of course it can run in either GUI mode using swing or command line mode on the unix shell.

 

Questions welcomed,


 

Thank you for your interest!

We will contact you as soon as possible.

Send us a message

Oops, something went wrong
Please try again or contact us by email at info@tikalk.com