>> NBI Project page

Developer's Guide to the NBI Installer Engine

This document provides information about how to create components and develop your own installers using the NBI installer engine (hereafter referred to as the installer engine). It explains the basic concepts for the installer engine, contains reference information, and provides step-by-step instructions for creating installable components.

This is a Preview version of the document, so all your feedback is welcome.

This guide assumes that you have some programming experience with the Java language and basic knowledge of Apache Ant.

Contents

top

Overview

The NBI Project is an open source development project for building an installer engine that provides an improved end user's installation experience. You can use this engine to build your own cross-platform Java-based installer. The main customer of the NBI Project is the NetBeans IDE.

The following concepts underlie the architecture of the NBI installer engine.

Flexibility. In the context of the installer, flexibility has the following meanings:

  • Flexible installation procedure. End users can install or uninstall separate components during one installation session.
  • Flexible operation modes. You can build two types of installers using the NBI engine: a traditional "bundled" installer that needs to be downloaded and executed on the user's machine, and a Java Web Start based installer that can be launched directely from a web page.
  • Flexible list of components. Each time the engine starts on a local machine, it connects to a server to identify a list of installable components. If new components have been added to a server, the user can immediately see these new installation options on the installation wizard pages and can decide whether to download them.

Separation of the engine from the installation data. In the installer, the engine is completely separated from the installation data, which includes software bits and configuration logic. This approach has been used to provide the flexibility of the installation flow.

For example, in JWS-based installer mode when the user starts a download for the first time, only the NBI engine is downloaded. The components' installation data is downloaded on an "as-needed" basis, and this process is handled by the engine without any additional user interaction. This minimizes the download size because the user does not need to download the components that are not needed.

Ability to create installable components of any complexity. In the installer, any additional logic that might be required for installation is packaged with the component. This data is downloaded together with the software bits only when needed. In turn, the engine provides a set of utilities that can interact with the component's configuration logic. Thus, you can use the installer to install almost any application, regardless of the complexity of its configuration.

Integration with the installed components. Using the API available in the installer engine, you can enable the installer to automatically install updates or ugrade the installed components.

top

NBI Architecture

The NBI installer engine contains three main modules: Product Registry, Wizard Framework, and Utilities. The Utilities module includes a sub-module, the Download Manager. This section describes the general workflow of the NBI engine and the role each module plays during installation.

General Workflow

The NBI engine workflow is roughly divided into five steps, which are initialization, components selection, uninstallation, installation, and finalization.

During initialization, the engine modules are initialized, command-line parameters are parsed, the serialized registries are loaded from the XML file, and the global components tree is constructed. Initialization of engine modules means that the required properties are set to either default values or custom values that are passed through the environment.

At the components selection step, the user selects the operations to perform on the components available in the global tree. These operations include no action, install, and uninstall. Based on this selection, the statuses of components are modified and the integrity of the resulting state of the system is verified. This means that the dependencies between the components to install are satisfied and all conflicts are resolved. In addition, the configuration logic for the selected components is downloaded and wizard pages for selected components are shown to gather user input if required.

Note that the components selection step is mandatory in the core NBI engine. However, for engine extensions, this default behavior may differ or this step can be completely omitted. The same applies to all other steps. However, it is highly undesirable to exclude initialization and finalization.

The workflow during uninstallation and installation is pretty straightforward. During uninstallation, the components selected for uninstallation are removed from the target machine. At the installation step, the installation data for the components to install is downloaded or extracted from an archive file, and these components are installed on the system.

The finalization phase consists of only one operation: the global components tree is serialized to the local registry.

The most important concept is that the installation and uninstallation phases are not differentiated in the NBI workflow. In this aspect, the NBI engine acts more like a package manager rather than a traditional installer. However, also note that the general workflow described above can be modified or even turned into the "traditional" scheme by using the so-called engine extensions.

Wizard Framework

The Wizard Framework module provides means for interaction between the engine and user and also serves as a workflow controller. The workflow steps described above are recorded in the wizard framework and executed by the wizard.

The wizard is organized roughly following the MVC scheme. It iterates over a set of so-called wizard components, and each of these components has a number of UI objects that constitute the interface the user sees.

Product Registry

The Product Registry module provides the model for the NBI engine. It stores information about installable components: their structure, various metadata, statuses, etc. It also provides a query mechanism and methods for working with the components: download/install/uninstall.

The NBI engine differentiates between three types of registries: local, bundled, and remote. All these types have the same structure and behavior. However, their location and purposes are different. The local registry is stored on the target machine and used to keep track of the components that are installed on the user system. The bundled registry is used when the engine is run from a bundle, i.e. when some components' installation data is bundled with the engine into a single package. All other registries are considered to be remote. The registries are stored on hard disk as XML files. This facilitates the tasks of manually editing the registries, creating "dynamic" registries by any server-side technology and, optionally, digitally signing them.

When the engine starts, it loads the registries and merges them into a single components tree, on which it will operate during an installation/uninstallation session. The registries are loaded in the following order: local (if it does not exist, an empty registry is created), bundled (if there are no bundled components, an empty registry is created), and remote (if there are several remote registries, they are loaded in the same order as they were registered). Note that when the registries are being loaded, a single component can be loaded only once. For example, if the NetBeans IDE 6.0 is already installed and, hence, is present in the local registry, it will be ignored even if it is present in the bundled or any remote registry. This means that the order in which the registries are loaded is very important and a particular component cannot be present twice in the resulting components tree.

When the engine execution finishes, the components whose status is installed are stored in the local registry.

[TBD: an illustration of registries handling process]

Utilities

The Utilities module provides helper procedures and objects for the engine and the components' logic. These include:

  • SystemUtils – Provides data about the target system and performs system/platform-specific operations
  • FileUtils – Provides methods for working with the filesystem and files
  • StringUtils – Contains a bunch of helper methods used to work with strings and the serialization/deserialization routines for helper objects
  • XmlUtils – Functions similarly to StringUtils but works mainly with XML files

A separate sub-module of the Utilities module is the Download Manager, which uses a URI as the input and downloads the contents of the URI to a specified file. At the moment, the following three types of URIs are supported:

  • file: – Point to a location in the filesystem
  • http: – Specify a URL
  • resource: – Specify the resources on the classpath of the engine

The Download Manager allows the engine to be indifferent to the input type to some extent. Thus, the engine does not care where the required resources are located because it is the Download Manager that handles the URI type. For example, the remote registries can be located on a remote server accessible via HTTP or on a local filesystem, and the engine will handle all of them in the same manner.

top

Configuring the Development Environment

To successfully develop installable components, the following initial configuration steps are required on the development machine.

Installing the Required Software and Libraries

Before you begin, you must install the following software on your computer:

  1. Java Development Kit (1.5.0_10 or newer is preferred, but not 1.6.0), which can be downloaded from http://java.sun.com
  2. NetBeans IDE (recent 6.0 builds are preferred), which can be downloaded from http://www.netbeans.org
  3. NetBeans C/C++ Pack (recent 6.0 builds are preferred), which is available at http://www.netbeans.org
  4. Apache Ant (1.6.5 is preferred), which can be downloaded from http://ant.apache.org
  5. GlassFish Application Server (either v1 or v2), which can be downloaded from http://glassfish.dev.java.net
  6. The cvs, gcc, make, ssh, and scp utilities for your operating system.
    For Windows, the recommended software are the Cygwin versions of these utilities available at http://www.cygwin.com

On the Windows platform, you also need a UNIX environment emulator, for example Cygwin or MKS (Cygwin is the recommended option).

Configuring the NetBeans IDE

Because some NetBeans projects for NBI components require the Ant1.6.5 library, you need to create this library.

To create the Ant1.6.5 library:

  1. In the NetBeans IDE, choose Tools > Library Manager and click the New Library button.
  2. Enter Ant1.6.5 as the library name and click OK.
  3. In the Library Manager window, click Add JAR/Folder and select the .jar files from your ant installation's lib subdirectory.

Additionally, for the NetBeans projects for NBI components, the Java platform must be named JDK 1.5. Thus, make sure that this version of the Java platform exists and points to JDK 5.0.

To verify the Java platform version:

  1. In the NetBeans IDE, choose Tools > Java Platform Manager.
  2. In the Java Platform Manager window, check that JDK 1.5 is listed under the Platforms category.
  3. If JDK 1.5 is not registered, click Add Platform, browse for the JDK 5.0 installation directory, and click Next.
  4. At the Platform Name page, type JDK 1.5 in the Platform Name field and click Finish.

Configuring the System

To ensure that the engine's native modules build properly, create a symbolic link from your JDK installation directory to /usr/java.

To create a symbolic link:

  1. Open the terminal window.
  2. Type the following: ln -s <path-to-jdk-directory> /usr/java

Note: For Windows, use the Cygwin terminal window rather than the Windows command-line program.

Obtaining Sources

The NBI sources are located in the NetBeans CVS repository. You can use the CVS root :pserver:anoncvs@netbeans.org:/cvs for anonymous access. The anoncvs account has a blank password and has read-only access to the repository. You need to check out the nbi module. See CVS Access to learn more about checking out sources from the CVS repository.

The nbi module has the following directories:

  • engine
    Contains the NetBeans projects with sources for the core NBI engine.
  • infra
    Contains the sources for various infrastructure entities, such as the server-side application, build system and utilities.
  • www
    Contains the http://nbi.netbeans.org web site pages.

Compiling and Deploying the Server Application

Before you start developing a component, you must set up the server-side application.

To set up the server-side application:

  1. If necessary, register the installed GlassFish server in the IDE by choosing Tools > Server Manager.
  2. In the IDE, open the infra/server project.
  3. Open the file infra/server/modules/ejb/src/java/org/netbeans/installer/infra/server/ejb/Manager.java and change the value of the ROOT constant to match your environment.
    For example, change the original value of the ROOT constant, which is
    	public static final File ROOT = new File("D:/temp/nbi-server/dev"); 
    
    to
    	public static final File ROOT = new File("<path-to-directory>");
    
    where <path-to-directory> is a directory that stores the server application's data.
  4. Build and deploy the infra/server project.
    Determine whether the project is running by accessing http://localhost:8080/nbi/dev/admin in the browser. The NBI registries management console should be displayed.
    Note: Port 8080 is the default HTTP port for the GlassFish server software. The HTTP port of your GlassFish server instance might differ from the default port.

Compiling and Deploying the NBI Installer Engine

The last configuration step before you can start developing a component is to build and deploy the engine.

To build and deploy the NBI installer engine:

  1. In the IDE, open the engine project and build it.
    The nbi-engine.jar file appears in the engine/dist directory.
  2. Go to http://localhost:8080/nbi/dev/admin and choose Update Engine from the top menu.
  3. Enter the path to nbi-engine.jar in the pop-up window and click Submit.
  4. Verify that deployment completed successfully: the nbi-engine.jar file must appear at the location specified by the ROOT constant.

top

Authoring Installable Components

This section describes how you can create installable components for the installer engine.

Installable components for the installer engine can be of the following types: product components or group components. Product components represent software pieces that will be installed on target systems by the installer engine. Group components are logical aggregations used to group the products in a components tree.

Creating a Simple Product Component

After you have completed all the steps described in the previous section, you are ready to start developing a simple product component.

In general, the development cycle includes the following steps:

  • Implementing the configuration logic
  • Creating a build system to build the component package and deploy it to the server
  • Running the installer to verify that the component is installed correctly

Implementing the Configuration Logic

The NBI build system expects that the configuration logic for a product component is a NetBeans project. Therefore, to implement this logic, you must create a new NetBeans Java Class Library project and register the engine project as one of its libraries. This Java Class Library project is referred to as the configuration logic project.

To create a configuration logic project and register a library:

  1. In the IDE, choose File > New Project, select Java Class Library as the project type, and click Next.
  2. At the Name and Location page, specify the name and location for the new project and click Finish.
  3. In the Projects window, expand the project's node, right-click the Libraries node and choose Add Project from the pop-up menu.
  4. Specify the path to the engine project and click Add Project JAR Files.
    The engine project is registered as a library for the new Java Class Library project.

The configuration logic is a single class, which extends org.netbeans.installer.product.component.ProductConfigurationLogic. The class must have a default constructor.

There are three methods that must be implemented by your configuration logic class:

  • getWizardComponents()
    Using this method, you can specify the number of custom wizard pages that will be displayed before actual installation starts. Typically, these pages are used to collect user input for correct configuration of the product. For example, one of these pages is a "destination" page, where the user can select the installation directory for the product. However, if you do not want to have any custom wizard pages, let the method return an empty list of WizardComponent.
  • install(Progress)
    This method is called after the product's files are copied to the installation directory and, optionally, decompressed using the unpack200 utility. Note that the files can be compressed automatically during build-time. Thus, the install(Progress) method implements any additional configuration that is required by the product, such as adding proper paths to configuration files. If you do not want to introduce additional operations, configure this method to inform the supplied progress object that the operation has finished: progress.setPercentage(Progress.COMPLETE);
  • uninstall(Progress)
    This method is called before the product's files are removed from the target machine. The logic implemented by this method performs custom cleanup operations, such as removing desktop shortcuts, services, etc. If you do not want to implement any custom configuration, you can leave this method empty and only inform the supplied progress object that the operation has finished: progress.setPercentage(Progress.COMPLETE);

The next step is to add a reference to your configuration logic class in the manifest file of the configuration logic project. Add the following entry to the manifest file: the entry name is Configuration-Logic-Class and its value is the classname of the configuration logic class.

Build the configuration logic project and check that it compiles correctly.

Before setting up the build system, you need to add the metadata for the product component: its display name, description, and icon.

To add metadata for the product component:

  1. In the root of your configuration logic project, create the data subdirectory.
  2. To the data subdirectory, add the following files:
    • icon.png, which is a 16x16.png image that will be used as the product's icon.
    • Bundle.properties, which contains two entries: product.display.name and product.description.
      The entries in the Bundle.properties have the following format:
      product.display.name=My Product
      product.description=My Product is the first NBI product component.

Setting up the Build System

For the detailed description of the NBI build system, see the NBI Build System chapter of this guide. This section describes how to create a build script for the product component you have created.

To beging creating the build script, you can use two templates, product-template.properties and product-template.xml, which are located at infra/build/.common/.templates/product.*.

First, copy the template files to another location. Then, rename the product-template.properties and product-template.xml files to build.properties and build.xml, respectively. You do not need to modify the build.xml file unless you want to add some custom behavior.

In the build.properties file, configure the following properties:

  • ${common.dir}
    Path to the infra/build/.common directory from the location for your build script.
  • ${cvs.path}
    Name of the directory that contains the sources of your configuration logic project.
  • ${product.uid}
    The unique identifier of your product. Use only lowercase alphabet characters and dashes.
  • ${product.version}
    Version of the product, which must be written as A.B.C.D.E, where A, B, C, D and E are nonnegative integers.
  • ${product.data.1.uri} and ${product.data.1.zip}
    Location of the installation data for the product, for details see Properties Specific of Project Types.

Specify the installation directory for the product. You can define the installation directory as follows:

  1. Set the value of ${product.properties.length} to 1.
  2. Uncomment the ${product.properties.1.name} and ${product.properties.1.value} properties.
  3. Set the ${product.properties.1.name} property to installation.location.
  4. Set the ${product.properties.1.value}property to $N{install}/myproduct, where $N{install} is a special string that will be replaced at runtime by a platform-dependent standard folder for new applications, for example, %ProgramFiles% on the Windows platform.

You have set up the build script for your product component.

Building and Deploying the Product Component

Now you can try to build and deploy the product component you have created.

To build and automatically deploy the product, call the release-all target from the product's build script. Then, specify the following properties by using the command-line interface or by modifying the properties file. Because these properties are specific to the build environment, they do not have any default values. For details, see Environment Properties and Instance Script Properties.

  • ${checkout.sources} - Set this property to false, because your product sources are apparently not in the CVS repository yet.
  • ${cvs.module} - Specify the name of the parent directory of the configuration logic project's folder.
  • ${sources.dir} - Provide the path to the parent directory for ${cvs.module}.
  • ${build.engine} - Set this property to false if you do not want to build the engine each time the product is built.
  • ${engine.dist.file} - Provide the path to the nbi-engine.jar file. For details, see Compiling and Deploying the NBI Installer Engine.
  • ${release.url} - Specify the URL of the server application on which the product package should be deployed. In this example, http://localhost:8080/nbi/dev/admin. For information, see Compiling and Deploying the Server Application.
  • ${release.registry} - Provide the name of the NBI registry to which the product should be added, for example, My Registry.
  • ${release.parent.uid} - Leave it blank for now.
  • ${release.parent.version} - Leave it blank for now.
  • ${release.parent.platforms} - Leave it blank for now.
  • ${packaged.data.dir} - Specify the path to the local packaged data repository. This can be any path to an existing directory.
  • ${downloads.cache.dir} - Specify the path to the local downloads cache directory. This can be any path to an existing directory.
  • ${jarsigner.keystore} - Specify the path to the keystore used to sign the package JAR file.
  • ${jarsigner.alias} - Provide the alias value for the keystore.
  • ${jarsigner.storepass} - Specify the password used to access the keystore.

After you have specified the required properties, run the release-all target to build and deploy the product component. To verify that the product has been deployed sucessfully, go to http://localhost:8080/nbi/dev/admin and check whether My Product is present in the components tree.

Running the Installer

To run the installer that contains your product component:

  • Go to http://localhost:8080/nbi/dev/registries, make sure that My Registry is checked, and click Install Now.
    After this, the installer engine runs automatically using Java Web Start and you can install the product component you have created.

top

Creating a Simple Group Component

The process of creating a group component is much simpler than creating a product component. The development cycle includes the following steps:

  • Adding metadata
  • Setting up the build system

Adding Metadata

The metadata for a group component is the same as for a product and include the display name, description, and icon.

To add metadata:

  1. Select a parent directory that will contain the group's sources and create the data subdirectory.
  2. To the data subdirectory, add the following files:
    • Bundle.properties, which contains two entries: group.display.name and group.description.
    • icon.png, which is a 16x16 .png image that will be used as the group's icon.

Setting up the Build System

For the detailed description of the NBI build system, see the NBI Build System chapter of this guide. This section describes how to create a build script for a group component.

To get started with creating the build script, you can use two templates, which are located at infra/build/.common/.templates/group.*.

First, copy the template files to another location. After that, rename the group-template.properties and group-template.xml files to build.properties and build.xml, respectively. In fact, you do not need to modify the build.xml file unless you want to add some custom behavior.

In the build.properties file, configure the following properties:

  • ${common.dir}
    Path to the infra/build/.common directory from the location specified for your build script.
  • ${cvs.path}
    Name of the directory that contains the sources of your group component.
  • ${product.uid}
    The unique identifier of your group. Use only lowercase alphabet characters and dashes.

Building and Deplopying the Group Component

In general, building a group component is similar to building a product component. Define the same environment properties as for the product component and run the release-all target. The build should complete successfully. See Building and Deploying the Product Component for details.

Adding the Product Component to a Group

After you create a group, you can make a product component to appear within this group. To do so, you need to modify the product component's build script.

To add a product component to a group:

  1. In the build script of the product component, set the ${release.parent.uid} property to the uid of the group.
  2. Run the release-all target in the product's build script to rebuild and redeploy the product.

To verify that the product has been added to a group, go to http://localhost:8080/nbi/dev/registries in your browser, make sure that My Registry is checked, and click Install Now. When the installer starts, you can see the group in the components tree and the product component is displayed under this group.

top

NBI Build System

Using the NBI build system, you can build two types of packages: the NBI engine package and component packages. Components can be of the following two types: product and group components.

The NBI engine package is a signed JAR file, which contains compiled classes and resources of the installer engine. Component packages, referred to as NBI packages, are created by building either a product component or a group component.

NBI Packages

The NBI package is the main format used to redistribute NBI components between various registry servers. An NBI package is a JAR file which consists of the following two parts:

  • Package descriptor. This is an XML file that copies the structure of the NBI registry. In fact, the XML file is a registry that describes the components whose data is available in the package.
  • Components' data. The number of these files varies for different component types. For example, for products, the data files include configuration logic JAR files, installation JAR files, and the icon. For groups, the components' data include only the icon.

NBI packages have the following structure:

    *  /  (package root)
          o registry.xml (package descriptor)
          o products/ (root for the products' data)
                + {product.N.uid}/ (product's uid)
                      # {product.N.version}/ (product's version)
                            * {product.N.platforms}/ (product's supported platforms, space-separated)
                                  o data/ (product's installation data)
                                        + data,K.jar (product's installation data file)
                                  o logic/ (product's configuration logic)
                                        + logic,K.jar (product's configuration logic file)
                                  o icon.png (product's icon)
          o groups/ (root for the groups' data)
                + {group.N.uid}/ (group's uid)
                      # icon.png (group's icon)

The package descriptor must reference the packaged components' data using resource URIs, for example resource:products/glassfish/2.0.0.0.20070213/windows/data/data,1.jar.

The NBI build system can build packages that contain either a single product (when a product build script is used) or a single group (when a group build script is used).

Organization of the Build System

Technologies

The NBI build system is based on Apache Ant. In addition, the following utilities are required:

  • cvs - for checking out project's sources
  • ssh and scp - for interacting with satellite machines, which are remote systems used to build the native components of the project
  • gcc and make - for building the native components

Build Process Overview

In general, the build process includes the following steps:

  1. The build process is initiated on the main machine (the so-called host machine).
  2. The build script is initialized.
  3. The local working directory and the build output directory are cleaned up.
  4. The project's sources are checked out (or copied from the specified location on the local system).
  5. If the project has native components that need to be built, the following operations are performed using the ssh and scp utilities for each of the platforms supported by the native components:
    1. The working directory is cleaned up on the satellite machine.
    2. Sources for the native components of the project are checked out.
      Note: The native components' sources on the satellite machine are always checked out from the CVS repository, even if they were copied from the specified location on the host machine.
    3. The native component is built.
    4. The native component is copied back to the host machine.
  6. If the project has a NetBeans part that needs building, the corresponding target is called in the NetBeans project's build script.
  7. Any required additional packaging is performed.
  8. The resulting package is released to the specified registries server.

Build Process Steps

The build process for any type of projects is divided into five major steps: initialization, clean-up, checkout, build, and release.

Initialization is required for all other steps. The only purpose of the initialization step is to build custom ant tasks if they are required, and register them in the script. In addition, some properties that are used throughout the build process are defined at this step. The values of these properties are based on the values passed in through the environment.

Cleaning up is a very straightforward process. At first, this process checks whether the native components of the project should be built and, hence, cleaned up. If there are components that need to be cleaned, the local distribution files of those components are deleted. Then, if the NetBeans part of the project needs to be built, the 'clean' target is invoked on its build script. Finally, the local working directory is deleted and the distribution file is deleted from the build output directory.

During checkout, the project's sources are checked out using the following CVS properties: root, branch, module, and path within the module. In addition, localized files from the translatedfiles module should be checked out and copied to the main source tree. If you have a copy of source files on the local machine, you can specify the path to this directory. In this case, the sources will be copied from the specified directory rather than being checked out from the CVS repository.

The build step is the most intense one. At first, native components are built on satellite machines using the ssh and scp utilities. Then, the NetBeans part of the project is built (see the Build Process Overview section for defails). The remaining operations vary for different types of projects: for products, the configuration logic and installation data files are downloaded and packaged; for groups, only the icon is downloaded; for the engine, no additional steps are performed. After packaging completes, the resulting distribution file is signed and copied to the build output directory.

The release step includes only one operation. This is releasing (or deploying) the distribution file to the specified registries server.

Build System Files

The core build system consists of four script files (common.xml, engine.xml, product.xml, and group.xml) and four properties files for these scripts (common.properties, engine.properties, product.properties, and group.xml.properties).

The common.xml file is a top-level base script that contains basic implementation of the build process steps described above. These steps are customized in the derivative scripts for different packages (engine.xml, product.xml, and group.xml). The common.xml script also leaves several loose hooks to allow a derivative script to insert some custom functionality before or after each build step. This approach facilitates customization of build steps because you do not need to modify the step's main target.

The engine.xml, product.xml, and group.xml files are derivative scripts from the common.xml top-level script for each project type: NBI engine, NBI product, and NBI group. They extend the functionality provided in common.xml and customize it to the specifics of the each project type.

However, these scripts are not to be used directly. They need to be extended by the so-called instance scripts. Each instance script is expected to provide the values of the properties that describe a specific instance of a certain project type. These instances can be a specific product, a group, or an engine (or engine's extension). To unify the look and structure of instance scripts, the build system has templates that can be used by instance script authors.

Thus, the general inheritance scheme for a build script that uses the NBI build system looks as follows:

  • common.xml
    • engine.xml or product.xml or group.xml
      • an instance script

The build system files are located in the infra/build/.common directory under the NBI sources root.

Build Script Templates

The build system provides three template files (engine-template.xml, product-template.xml, and group-template.xml) and three properties files for these scripts templates (engine-template.properties, product-template.properties, and group-template.properties).

You can use these templates to write your own instance scripts for one of the project types: NBI engine, NBI product, and NBI group. For example, if you want to write an instance script for the NBI engine, rename the engine-template.xml and engine-template.properties files to build.xml and build.properties, respectively. Then, edit the build.properties file to match your build environment.

The template files are located in the infra/build/.common/.templates directory under the NBI sources root.

top

Environment Properties and Instance Script Properties

The build system expects that a number of properties are supplied by the user when a build script is invoked. Some properties change more often than others. The properties that change more often should be specified using the ${environment.properties} property, which points to a file that contains all properties. The properties that change less often are specified in the instance script's properties.

Below is the list of properties which you can use to control the build process. Some of them are mandatory, while others are optional. Note that it is more convenient to specify some properties in the environment properties file, while it is better to define other properties in the instance script's properties file.

Properties for the Host Machine

All these properties are mandatory and expected to change quite rarely. Therefore, we suggest placing them in the instance script's properties file.

Property Meaning
${common.dir} Path to the directory that contains the base scripts
${work.dir} Path to the local working directory
${dist.dir} Path to the local build output directory

Properties for Satellite Machines

You can build native components only on satellite machines. If satellite machines are used, all properties listed in the table below are mandatory. You must specify these properties for each platform supported by the native components you are going to build. The platforms include following: windows, linux, solaris-x86, solaris-sparc, and masosx.

These properties are expected to change quite rarely, but since they normally contain some confidential information, it is better to store them separately from build scripts and probably outside of the version control system.

Property Meaning
${remote.host.<platform-name>} Host name of the satellite machine for the specified platform
${remote.port.<platform-name>} Port on which the satellite machine accepts ssh connections
${remote.user.<platform-name>} User name used to connect to the satellite machine

Properties that Control Checkout of Sources

These properties specify the CVS attributes of project's sources. They also define whether these sources need to be checked out from the CVS repository or copied from another location. Most of these properties are specified in the instance script's properties file, except for ${checkout.sources} and ${sources.dir} that can be defined in the environment properties file.

Note: If you specify another location (not a CVS repository) from which to download sources, this setting does not affect the process of building native components. The native components' sources are always checked out from the CVS repository.

Property Meaning
${checkout.sources} Specifies whether to check out sources from the CVS repository or copy them from another location. This property can have only two values: true or false.
${cvs.root} The CVS root for the repository that contains project sources.
${cvs.branch} Name of the branch to check out. If no value is specified, the trunk is checked out.
${cvs.timestamp} Timestamp of the sources to check out. If no value is specified, the latest sources are checked out.
${cvs.module} Name of the module to check out.
${cvs.path} Path to the directory with sources to check out. This path is relative to the root of the cvs module.
${sources.dir} Path to a local directory with sources. Specify this property only if ${checkout.sources} is set to false.
${sources.params.length} Length of the list of sources' parameters.
${sources.params.N.token} Token of the sources' parameter with index N, where N can change from 1 to ${sources.params.length}
${sources.params.N.value} Value of the sources' parameter with index N.

Properties that Control the Build Process

These properties let you specify the parts that should be built or not built. Note that these properties have default values for each project type, so they should be handled with serious care.

Property Meaning
${dont.build.custom.tasks} If this property is set, the initialization process will not build the custom ant tasks required for the project. You must specify a valid value for ${custom.tasks.cls}, which is a path to a directory that contains compiled custom task classes.
${build.native} Specifies whether to build the native components of the project. This property can have two values: true or false
${build.nbproject} Specifies whether to build the NetBeans part of the project. This property can have only two values: true or false.

Properties Specific of Project Types

Because the build scripts for each project type contain different functionality, there are properties that can be used only for particular project types. These properties define how the script behaves in the areas specific of this project. It is better to specify most of these properties in the instance script's properties file.

For the NBI engine, you do not need to specify any additional properties.

The following table lists properties for the NBI product project type.

Property Meaning
${build.engine} Specifies whether to build the engine. The default value is true. This property is overridden by the environment properties if it is not required to build the engine.
${engine.dist.file} Path to the pre-built engine file. This property is effective if ${build.engine} is set to false.
${package.data} Defines the script's behavior related to data packaging. If the value is true, the data is always repackaged (using pack200). If the value is false, the data will be treated as is. If the value is default, an attempt will be made to fetch the prepackaged data from the local packaged data repository and if this attempt fails, the data will be retrieved from the original location and repackaged.
${release.packaged.data} Specifies whether to "release" the packaged data to the local packaged data repository.
${packaged.data.dir} Path to the local packaged data repository.
${downloads.cache.dir} Path to the local downloads cache directory.
${product.uid} Product's uid.
${product.version} Product's version.
${product.platforms} List of platforms supported by the product
${product.status} The initial status of the product. In most cases, the value is not-installed.
${product.offset} The offset of the product's node. The lower the offset value, the closer the product's node to the top of the nodes list.
${product.expand} Specifies whether to expand the product's node.
${product.visible} Specifies whether the product's node is visible.
${product.features} A space-separated list of features this product belongs to.
${product.logic.length} Length of the list of product's configuration logic files.
${product.logic.N.uri} The URI of the product's configuration logic file with index N, where N varies from 1 to ${product.logic.length}
${product.data.length} Length of the list of product's installation data files
${product.data.N.uri} The URI of the product's installation data file with index N, where N varies from 1 to ${product.data.length}
${product.data.N.zip} Type of the product's installation data file with index N, where N varies from 1 to ${product.data.length}. This property can have two values: true or false. If set to true, the product data file specified by ${product.data.N.uri} is a ZIP file that should be extracted before it is imported into the package. If set to false, the file should be used as is.
${product.disk.space.modificator} Correction to the required disk space property, in bytes. The base value is a sum of sizes of decompressed installation data files.
${product.requirements.length} Length of the list of product's requirements.
${product.requirements.N.uid} The UID of the product's requirement with index N, where N varies from 1 to ${product.requirements.length}.
${product.requirements.N.version-lower} Lower bound on version of the product requirement with index N.
${product.requirements.N.version-upper} Upper bound on version of the product requirement with index N.
${product.conflicts.length} Length of the list of product's conflicts
${product.conflicts.N.uid} The UID of the product's conflict with index N, where N varies from 1 to ${product.conflicts.length}
${product.conflicts.N.version-lower} Lower bound on the version of the product conflict with index N
${product.conflicts.N.version-upper} Upper bound onthe version of the product conflict with index N
${product.install-afters.length} Length of the list of product's "install-after" dependencies
${product.install-afters.N.uid} The UID of the product's "install-after" dependency with index N, where N varies from 1 to ${product.install-afters.length}
${product.properties.length} Length of the list of product's properties.
${product.properties.N.name} Name of the product's property with index N, where N varies 1 to ${product.properties.length}.
${product.properties.N.value} Value of the product's property with index N.


The following table lists properties for the NBI group project type.

Property Meaning
${group.uid} Group's UID.
${group.offset} The offset of the group's node. The lower the offset value, the closer the group's node to the top of the nodes list.
${group.expand} Specifies whether to expand the group's node.
${group.visible} Specifies whether the group's node is visible.
${group.properties.length} Length of the list of group's properties.
${group.properties.N.name} Name of the group's property with index N, where N varies from 1 to ${group.properties.length}.
${group.properties.N.value} Value of the group's property with index N.

Miscellaneous Properties

These properties do not fall into any category, but they are important for the build script to run correctly.

Property Meaning
${jarsigner.keystore} Path to the local keystore that is used to sign JAR files
${jarsigner.storepass} Password for the keystore
${jarsigner.alias} Keystore alias

top

Configuration of Build Machines

Host Machine

The following software must be installed and configured on the host machine:

  • J2SE Development Kit 5.0 Update 10 or newer
  • Apache Ant 1.6.5 or newer
  • Modern versions of cvs, ssh and scp utilities.
    For Windows systems, the cygwin versions of these utilities are recommended.

These programs should be present in the PATH environment variable.

Satellite Machines

The following software must be installed and configured on each satellite machine:

  • Modern versions of cvs, ssh and scp utilities.
    For Windows systems, the cygwin versions of the utilities are recommended.

These programs should be present in the PATH environment variable.

Note: Since an ssh connection from the host machine to satellite machines is established automatically, no manual user input is assumed. Therefore, the ssh connection between these machines should be configured so that no user intervention is required, for example using public-key authentication.

top

References

Progress Objects

Classes

  • org.netbeans.installer.utils.progress.Progress [TBD: link to javadoc]
  • org.netbeans.installer.utils.progress.CompositeProgress [TBD: link to javadoc]
  • org.netbeans.installer.utils.progress.ProgressListener [TBD: link to javadoc]

Description

Progress objects can be used to track the progress of potentially lengthy operations. They can be used instead of the commonly used “listeners” infrastructure. Progress objects use the listeners infrastructure to ensure synchronization and notify interested parties about the progress status.

For example, a client that needs to invoke a lengthy operation creates an instance of a progress object and passes it to a procedure handler, which is typically a method in another class. As the operation progresses toward its completion, the procedure handler updates the progress properties. At the same time, the client can either watch the operation progress and read notifications about the progress status or pass the data to a GUI which displays a progress bar.

Progress objects allow information to pass to the procedure handler, which provides the option of cancelling an operation. In order to cancel an operation, a client must call the setCanceled method on the progress. The rest depends on the procedure handler. The canceled value serves as a recommendation to terminate the operation and return. However, under certain circumstances, the procedure handler can ignore the signal and continue the operation until it completes.

Using progress objects, you can synchronize two progresses. This can be useful when the client passes the general instance of a progress object to the procedure handler, but the handler needs to operate on a special instance of this object. The procedure handler can instantiate a special instance of the progress object and set this instance to synchronize with the original object that was passed as an input parameter.

To handle operations that consist of several steps, each of which requires separate progress, you can use the CompositeProgress object. The CompositeProgress object can handle and synchronize several child progresses and correctly report the status of the entire progress.

top

Wizard Framework

Classes

  • org.netbeans.installer.wizard.Wizard [TBD: link to javadoc]
  • org.netbeans.installer.wizard.components.WizardComponent [TBD: link to javadoc]
  • org.netbeans.installer.wizard.components.WizardAction [TBD: link to javadoc]
  • org.netbeans.installer.wizard.components.WizardPanel [TBD: link to javadoc]
  • org.netbeans.installer.wizard.components.WizardSequence [TBD: link to javadoc]
  • org.netbeans.installer.wizard.containers.WizardContainer [TBD: link to javadoc]
  • org.netbeans.installer.wizard.containers.SwingContainer [TBD: link to javadoc]
  • org.netbeans.installer.wizard.containers.SwingFrameContainer [TBD: link to javadoc]
  • org.netbeans.installer.wizard.ui.WizardUi [TBD: link to javadoc]
  • org.netbeans.installer.wizard.ui.SwingUi [TBD: link to javadoc]

Description

In the installer engine, the NBI wizard framework is used to inform the user about the installation progress and collect user's input data. The user navigates through a sequence of wizard's pages using UI controls. In most cases, these controls are the Next and Back buttons.

The framework is based on three main entities, which are roughly mapped to the MVC design scheme as follows:

  • Wizard serves as the controller.
  • A set of WizardComponent instances serve as the model.
  • WizardUi is the view.

The wizard framework supports the so-called "child" wizards, which are used to add subsequences or "child" sequences to the root wizard's workflow. Using child wizards, you can add an alternative sequence of pages branched from the root wizard. When going through installation, the user first completes the child sequence and then returns to the root wizard's pages. Child wizards can be used to conditionally execute sequences of pages without having to attach conditional logic to each page. This use case is implemented in the WizardSequence standard component.

The entry point to the wizard framework is the Wizard class. The installer engine creates the root wizard's instance using the static getInstance() method. This method loads the components for the root wizard's instance from the XML file that is defined in the system property (see the javadoc for the Wizard class for the exact name of the property). If the system property is not set, the components are loaded from the default location. After the wizard's instance is created, you can use the open() and close() methods to start (show) and finish (hide) the wizard, respectively. It is possible to programmatically navigate between the components using the next() and previous() methods. You can use the next() and previous() methods to programmatically navigate between the components.

The WizardUi and WizardContainer intefaces define the pluggable UI functionality for the wizard. The WizardUi is an abstraction over numerous UI modes, such as Swing, Console, SWT, etc. (Note that the wizard framework now supports only the Swing UI mode). Each instance of the WizardComponent class has an associated instance of WizardUi. These WizardUi instances are used by the wizard container to obtain a specific implementation to match the current UI mode. The Wizard class selects the wizard container that matches the currently active UI mode.

The WizardComponent class and its implementations represent a single step in the sequence of wizard pages. They contain the business logic of this step, whereas the WizardUi that corresponds to each implementation provides a visualization of this logic. WizardPanel, being the most frequently used component, shows the user one or several static messages or a set of input fields and validates the input. In contrast, WizardAction represents an action which does not require any user input and displays the progress of this action. The last standard wizard component, WizardSequence, allows conditional execution of a subsequence of child pages.

top

Appendices

Appendix A. Property Suffix Conventions

  • The properties that end with .dir indicate a full path to a directory that can be used directly (in contrast to partial paths). For example, ${cvs.dir} equals to ${work.dir}/${cvs.module}/${cvs.path}.
  • The properties that end with .path indicate a partial path, which should be used as part of a larger construct rather than directly. For example, ${cvs.path} is a part of the path to the project's sources from the root of the cvs module. Compare with the above example of ${cvs.dir}, which is a full path to the sources.
  • The properties that end with .file also indicate a full path to a file that can be used directly. In this sense, these properties are similar to those with the .dir end suffix. For example, ${nbproject.dist.file} is a path to the NetBeans project's distribution file.
  • The properties that end with .file.name indicate file names that can be used both separately and within larger constructs. In this sense, these properties are similar to those with the .path end suffix. For example, ${nbproject.dist.file.name} is the name of the distribution file for the NetBeans project.

Glossary

  • NBI components
  • NBI package (NBI product package, NBI group package)
  • Host machine
  • Satellite machine
  • Local working directory
  • Build output directory
  • Base script
  • Derivative script
  • Local packaged data repository
  • Product component
  • Group component
  • NBI registries management console

top

Project Features

About this Project

Installer was started in November 2009, is owned by Antonin Nebuzelsky, and has 49 members.
By use of this website, you agree to the NetBeans Policies and Terms of Use (revision 20160708.bf2ac18). © 2014, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo
 
 
Close
loading
Please Confirm
Close