Subsections


Custom Actions

(by Klaus BARTZ)

Overview

In general the installation procedure is separated into several steps. The first step, let's call it the data collection phase, is getting specific data needed for the installation process. Typically this is done by typing all neded data into one or more panels, if a GUI is used, or automatically by reading the data from a config file. In general nothing will be changed on the system until all needed data is obtained. But mostly - depending on to the information, e.g. the destination path - different input panels are involved.

If all needed data is collected the second step will be perfomed, let us call it the action phase. During this step the state of the locale machine will be changed, e.g. files will be copied to the installation destination or some short cuts will be registered. Each of this subsequent steps are denoted as actions. There are actions intended to be reused, so called common actions, and actions for one special purpose only, so called custom actions. In IzPack there are already some common actions, for example "file transfer", "parse" or "execute".

The third step, the reporting phase, is normally represented by a panel that reports the result state of the installation (OK, or not OK) and a simple good bye message.

With IzPack there are two ways to implement custom actions. Firstly it is always possible to define a custom panel that perfoms the desired actions too. Secondly, and that's the new, custom actions are supported.

Panels still may be used for actions that are perfomed, e.g. before files are transferred or after the "execute" action. But if the needed action depends on the selected or already installed packages, this works also, but the implementation effort is much higher.

If the action should be performed for several amount of elements of a pack, using custom actions will be more easy than using panels. Additional custom actions may be defined for installation, but also for packaging and uninstallation purposes. If a custom action is also needed for uninstallation purposes, it'll be always a good idea to implement a corresponding installation action as custom action, but not as panel.

How It Works

Custom actions are implemented as listeners. Each listener implements callback methods that will be called at well-defined points. The method InstallerListener.afterFile for example will be called after a file has been copied. There are different interfaces intended for being used at packaging time, at installation time and at uninstallation time.

Each interface is implemented by a class with the prefix "Simple" (e.g. SimpleCompilerListener) that implements all declared interface methods with an empty body. These classes may be used as base classes for own listener implementations.

To apply custom actions to the installer, an entry in the apropriate install.xml file is needed. The configuration of listeners starts with the facultative ELEMENT "listeners" which can contain one or more ELEMENTs of "listener". For a "listener" there are three attributes which determine the "compiler", "installer" and "uninstaller" custom action pupose. Additionally it is possible to make the listener OS dependent using the "os" ELEMENT.

If file related data will be set, the facultative ELEMENT "additionaldata" is defined for the ELEMENTs "file", "singlefile" and "fileset". This data will be automatically moved to the corresponding PackFile objects in the install.jar. Extraction and usage should be implemented in a install custom action (see example).

Custom Action Types

Custom actions are intended to be used at packaging time, at installation time and at uninstallation time. The interfaces are:

Custom action type Interface name
Packaging com.izforge.izpack.event.CompilerListener
Installation com.izforge.izpack.event.InstallerListener
Uninstallation com.izforge.izpack.event.UninstallerListener

Custom Actions At Packaging

UML Diagram

\fbox{\includegraphics[scale=1.0]{img/CompilerListener}}

Description

Custom Actions At Installing Time

UML Diagram

\fbox{\includegraphics[scale=1.0]{img/InstallerListener}}

Description

Custom Actions At Uninstalling Time

UML Diagram

\fbox{\includegraphics[scale=1.0]{img/UninstallerListener}}

Description

Package Path

Custom actions must always implement one of the given listener interfaces. As mentioned above, it is also possible to derive from one of the "Simple" listeners. The package path is facultative, only the class name must be unique over all custom actions. The preparation of a custom action for providing it with an installation is very similar to panels. Custom actions must also be packed into a jar file with the name of the custom action class name. This jar file should be placed in [IzPackRoot]/bin/customActions, may be
[IzPackRoot]/bin/customActions/MyCompilerListener.jar
[IzPackRoot]/bin/customActions/MyInstallerListener.jar
[IzPackRoot]/bin/customActions/MyUninstallerListener.jar
In the default Ant definition file (build.xml) there are some targets for this stuff.

Correlated Stuff

Native Libraries for Uninstallation

If a custom action uses JNI at installation time, often the associated uninstall custom action needs JNI too. For this situation it is possible to declare a native library for unstallation. The only work to do is to add a stage attribute to the native tag in the install xml file like
<!-- The native section. We specify here our os dependant
libs..--> <native type="3rdparty"
name="MyOSHelper.dll"stage="both" >
   <os family="windows" />
</native>

The needed additional classes are packed into lib/uninstaller-ext.jar. If a native library is defined for uninstallation, this file will also be packed into the installer.jar as IzPack.unistaller-ext and used at its right position.

What You Have To Do

Follow the steps that are needed to create and use custom actions with the "normal" source environment (not standalone compiler) using Ant. Of course, it works also with the standalone compiler.


Custom Actions at Packaging (CompilerListener)

Custom Actions at Installation Time (InstallerListener)

Perform the same steps as described in 7.3.1, replace all occurrences of "CompilerListener" with "InstallerListener" and "compiler" with "installer".

Custom Actions at Uninstallation Time (UninstallerListener)

Perform the same steps as described in 7.3.1, replace all occurrences of "CompilerListener" with "UninstallerListener"and "compiler" with "uninstaller".

Example

Let us say, we want to set access rights for files and directories on Unix. The Java sources are placed in the directory
[IzPackRoot]/sample/src/com/myCompany/tools/install/listener. There are the files ChmodCompilerListener.java and ChmodInstallerListener.java.

Ant Actions (InstallerListener and UninstallerListener)

In this section the common ant task custom actions are described in detail. It is only for developers who are not acquainted with IzPack or it's custom actions. In addition to the basics there are some recapitulations of the common custom action techniques and some hints for pitfalls.
In the package com.izforge.izpack.event there are the ant related custom actions AntActionInstallerListener and AntActionUninstallerListener. As recapitulation, to add any custom action a reference in install.xml will be needed, as example:
<listeners>
    <listener installer="AntActionInstallerListener"
        uninstaller="AntActionUninstallerListener" />
</listeners>

For all referenced listeners a jar file with the same name must exist in [IzPackRoot]/bin/customActions. If compilation (packaging) fails with a "not found" error, first verify, that the jar file exists. If not, create it.
With this custom action it is possible to perform ant calls at installation and/or uninstallation time. It is not only a wrapper for a comand-line ant call, but also an intersected description file defining what target of the ant build file should be performed at what time of (un)installation and specifies which properties for what IzPack pack are to be used. The intersected description file is written as XML, the corresponding dtd is placed in src/dtd/event/antaction.dtd. The description file should be declared as a resource in the install.xml with the id AntActionsSpec.xml e.g.

<resorces>
    ...
    <res id="AntActionsSpec.xml" src="myInstallSpecs/MyAntActionsSpec.xml" />
    ...
</resorces>

The precise spelling of the id is important. The base path of src is the installation project path. If you want to use ant, you have to specify it here. IzPack is designed for running without dependencies on external software or libraries. Therefore it is necessary to include everything needed, in this case ant self. The field <jar> in installation.xml is predestinated for such cases, e.g.

<jar src="jar/ant/ant.jar" stage="both" />

Be aware, that an "extended" ant use needs more than one jar, for example often xercesImpl.jar. If an obscure "class not found" exception is raised during testing, check first for missing jar files.
For supporting uninstallation the jar field was extended by the attribute stage. If an ant uninstaller custom action is used, the uninstaller also needs the jar files. If stage is "both" or "uninstall", the contents of the referenced jar file will be packed into uninstaller.jar. Be aware that not the jar file itself, but the contents of it are required. This implies, that the paths of the contained files are unique and the information in meta-inf/Manifest.mf will be lost.

The Basic XML Struture

An ant action will be defined in the resource with the id "AntActionsSpec.xml". Sometimes it will help to lock into [IzPackRoot]/src/dtd/event/antaction.dtd or validate a written xml file with the dtd.
On this xml file a substitution will be performed using all defined IzPack variables. It is performed just before processing the packs. This is a common way of loading spec files into custom actions. For more information see method com.izforge.izpack.util.SpecHelper.readSpec. If you want to substitute some custom item, simply add a variable via idata.setVariable in a custom panel before InstallPanel. The given variable name (id) should be written into the xml file in the common variable notation.

The top level XML section is called <antactions>. Only one is possible. The <antactions> are segregated in one or more <pack> elements. The single attribute <name> of the <pack> corresponds to the same structure in install.xml (for more information see also installation.dtd). Only the "things" included in the <pack> are performed, if a pack with the same name was chosen to be installed. The "things" to be done to self are defined by the element <antcall> (without ssss).
The <antcall> takes the following attributes:

In addition to the possible attributes there are some elements. All elements can be defined more than one time in one <antcall>. All are optional, but with no <target> element the <antcall> makes no sense. Do not confuse the following: "required"s are related to the attributes of the elements, not to the elements themselfs.


<property>: define a property

Property to be used with all targets and uninstall_targets which are defined for this antcall.


<propertyfile>: define properties in a file

Properties to be used with all targets and uninstall_targets which are defined for this antcall given by the path of a properties file.


<target>: target to call at installation

Targets to perform with this antcall at installation time. The targets should be defined in the given buildfile or else an ant exception will be raised. This is that what you use, if you don't want to perform the default target. e.g. cleaning the IzPack project with ant clean


<uninstall_target>: target to call on uninstallation

Targets to perform with this antcall at uninstallation time. The targets should be defined in the given buildfile otherwise an ant exception will be raised. With this target it will be possible to undo the things done at installation time.

Julien Ponge 2005-04-22