BSFInstallerListener and BSFUninstallerListener

BSFInstallerListener and BSFUninstallerListener are intented to add BSF (Bean Scripting Framework) scripting pre- and post-installation actions to an installation or uninstallation.

This way you can use scripting languages like Groovy, JavaScript, Jython etc. for custom tasks regarding the installation or uninstallation.

Basic Usage

To activate this feature, there must be appended the according listener depending on whether BSF scripts are to be used during installing or uninstalling (or both):

<listeners>
    <listener installer="BSFInstallerListener" uninstaller="BSFUninstallerListener" />
</listeners>

Additionally, both listener classes need a resource named BSFActionsSpec.xml to define the actions in particular:

<resources>
    ...
    <res id="BSFActionsSpec.xml" src="myInstallSpecs/MyBSFActionsSpec.xml" />
    ...
</resources>

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 used to add additional scripting libraries to the installer classpath, for example:

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

In addition, there must be also included the library for the language which you are going to use in your BSF scripts, including any additional language dependencies, for instance:

<jar src="jar/groovy/groovy-all.jar" stage="both" />

Finally, if you are NOT going to embed your script content in the "BSFActionsSpec.xml", but instead will be including it in an external resource, there must be also defined the according resource in the install.xml file (see below for an explanation):

<res id="actions.groovy" src="myInstallSpecs/actions.groovy" />

The BSFActionsSpec.xml XML Structure

A BSF action will be defined in the resource with the id BSFActionsSpec.xml.

IzPack variables are substituted here for your convenience before processing the packs.

In some languages, such as groovy and jython, you must create the function as a closure, so that the symbol is globally defined. In other languages (such as beanshell), you can create the function normally.

Example:

<bsfactions>

	<pack name="Core files">
		<script language="groovy" src="actions.groovy" />
    </pack>

	<pack name="Extension files">
		<script language="groovy"><![CDATA[
		  // Variables defined
		  //   idata - installer data, of type AutomatedInstallerData
		  //   npacks - # of packs selected
		  beforePacks = {
		    print "before packs";
		  }

		  // Variables defined
		  //   idata - installer data, of type AutomatedInstallerData
		  afterPacks = {
		    print "after packs";
		  }

		  // Variables defined
		  //   pack - pack information, of type Pack
		  //   i - the package index
		  beforePack = {
		    print "before pack " + pack.name;
		  }

		  // Variables defined
		  //   pack - pack information, of type Pack
		  //   i - the package index
		  afterPack = {
		    print "before pack " + pack.name;
		  }

		  // Variables defined
		  //   pack - pack information, of type Pack
		  //   file - the dir which is to be created, of type File
		  beforeDir = {
		    print "before dir " + file.absolutePath;
		  }

		  // Variables defined
		  //   pack - pack information, of type Pack
		  //   file - the dir which was created, of type File
		  afterDir = {
		    print "after dir " + file.absolutePath;
		  }

		  // Variables defined
		  //   pack - pack information, of type Pack
		  //   file - the file which is to be installed, of type File
		  beforeFile = {
		    print "before file " + file.absolutePath;
		  }

		  // Variables defined
		  //   pack - pack information, of type Pack
		  //   file - the file which was installed, of type File
		  afterFile = {
		    print "after file " + file.absolutePath;
		  }

		  // Variables defined
		  //   files - pack information, of type Pack
		  //   variables - the variables which were used during the original install, of type Properties
		  beforeDeletion = {
		    print "before deletion";
		  }

		  // Variables defined
		  //   files - pack information, of type Pack
		  //   variables - the variables which were used during the original install, of type Properties
		  afterDeletion = {
		    print "after deletion";
		  }

		  // Variables defined
		  //   file - the file which is to be deleted, of type File
		  //   variables - the variables which were used during the original install, of type Properties
		  beforeDelete = {
		    print "before delete";
		  }

		  // Variables defined
		  //   file - the file which was to be deleted, of type File
		  //   variables - the variables which were used during the original install, of type Properties
		  afterDelete = {
		    print "after delete";
		  }
		]]></script>

		<script language="beanshell"><![CDATA[
			void beforePacks() {
			    print "INSTALL_PATH=${INSTALL_PATH}";
			}
		]]></script>
	</pack>

</bsfactions>

The root level XML element is <bsfactions>.

The single actions to perform are assigned to one or more <pack> elements. The single attribute <name> of the <pack> corresponds to the same one of the according <pack> definition in install.xml.

Only the "things" included in the <pack> are performed, if the according pack the same name has been selected by the user to be installed. The scripts themself are defined by the element <script>.

The <script> takes the following attributes:

  • language: required.
    The name of the BSF language which is being used. The exact name of the language is dependent upon the BSF engine integration of that particular language. Some example values are "javascript" and "groovy".
  • src: optional:
    The name of a resource, defined in your installer.xml, which contains the script contents. This may be used in lieu of embeddeding the script contents in the BSFActionsSpec.xml file itself.

In addition to the possible attributes <script> can contain a CDATA section which contains the script content, rather than using the "src" attibute. The different installer/uninstaller phases are scripted by creating a symbol definition for that particular phase. The symbol will then be called by the listener (if present), and the appropriate phase variables defined. If a particular phase is not defined, it will be skipped.