Migrating to install4j 5

Those who made the move from install4j 3 to install4j 4 will remember that it was a lot of work to migrate custom code, because most core concepts had been changed.
Not so with install4j 5: Your old project file will be transformed to the new format and most projects will work right away, without the need for any manual work. If you are interested in the changes in the project file structure, please see the file config/transforms/transform_3.xsl in your install4j installation directory.

However, there are a number of cases where old functionality has been replaced, behavior has been changed or the API has been fixed. In those cases backwards incompatibilities can arise. This post intends to present an exhaustive list of them:

  • We have removed support for Java 1.3. This allows us to use the standard XML beans decoder and XML parser in the JRE. Java 1.4 is still supported.
  • The “Require admin user” action and the “Request admin privileges on Windows Vista” option on the “Installer options” step of the Windows media wizard have been removed. They have been replaced with a much more capable “Request privileges” action. The “Request privileges” action is now added to all projects by default and will be inserted into the “Startup” sequence of old projects as well. If you had a “Require admin user” action in your project, the “failure” properties will all be selected (they are otherwise not selected by default). If you had a condition expression on the “Require admin user” action, it will be lost. Especially platform-dependent configuration is now possible directly in the “Request privileges” action.
  • On the Installer->Custom Code tab, the old “Use installed JAR files if possible” option has been removed. Previously, the installer performed a two-phase initialization of screens and actions, before and after the “Install Files” action, so you could use custom code from installed JAR files. The main reason for that option was to prevent double packaging of JAR files, once for the installer and once for the launcher. In install4j 5, if entries in the custom code are also present in the distribution tree, they will be moved to the final destination by the “Install Files” action, and the custom code will automatically include the installed files in custom installer applications and the uninstaller. This change significantly improves custom code handling, because double packaging is always prevented and you can use such custom code before the “Install Files” action is executed.
    However, if your code depends on the location of the JAR file, this can be a breaking change and you have to change your custom code. In that case, the new Screen#isCreatedLazily() method and the optional Context#initializeLazilyCreatedScreens() method will help you to move the initialization of the custom screen after the “Install Files” action while the Context#addToClassPath(File) method allows you to add installed JAR files to the custom code for dependencies that only work in the installed location.
  • The compiler variable “sys.platform” now resolves to “windows-x64” for 64 bit media files. Previously, it always resolved to “windows”. This variable is used in the standard media file name pattern on the General Settings->Media File Options tab, so your 64-bit Windows media files will now be named differently if you have not changed or overridden the media file name.
  • There was a typo in the system message key name “LocateBrowerExecutable”. In the unlikely event that you used that key explicitly in your project before, it will lead to a runtime exception.
  • A few installer variable names have changed to make naming more consistent. The old names will be replaced automatically with the new names when you open your old project file for the first time. However, if you use them outside of the install4j IDE, for example in custom code, you will have to change them. The replacements are:
    • sys.mediaDirectory -> sys.mediaDir
    • sys.installerDirectory -> sys.installerDir
    • sys.programGroup.name -> sys.programGroupName
    • sys.programGroup.linkDir -> sys.symlinkDir
    • sys.programGroup.allUsers -> sys.programGroupAllUsers

  • (Updated on 2010-07-15) The “Services” screen has been removed. The reason is that since the service actions now support arbitrary service executables (not only those generated by install4j), it would be difficult for us to present a list like in 4.x. Also, we feel that this is really a technical question that users should not have to answer. If needed, you can create a question with a configurable form. The “Hello world” project has such a screen.

Other breaking changes only concern the API:

  • The method ApplicationRegistry.ApplicationInfo#getProgramGroup() has been removed from the API. It has been obsolete since 4.2, when the “Load reponse file” action was added. In the GUI, the “Suggest previous program group” option on the Installer->Update Options tab has been removed as well.
  • Several typos in method names have been fixed. Fortunately, typos were only discovered for the rarely used methods Context#isErrorOccurred(), Context#setErrorOccurred(boolean) and
    FormComponent#initialize(). If you are affected by the first two changes, the build will fail. If you derive a form component from AbstractFormComponent, the third change concerns a method that is overridden and would not cause a compilation error, so we have added a method for backwards compatibility in that case.
  • Several methods in the Install4jBeanInfo and Install4JPropertyDescriptor classes had their return values changed from void to the class itself in order to facilitate usages in builder patterns. You just have to recompile your code against the new runtime library, no source code changes are required.
  • The Context#getWizardContext() does not return null in unattended or console mode anymore. Instead, a dummy wizard context is returned that does nothing when its methods are invoked. If you use Context#getWizardContext() to check for those installer modes, you have to change your code and use Context#isUnattended()and Context#isConsole()instead.
  • The “installerAndUninstaller” argument from ActionBeanInfo#setAssociatedStartupAction(String) was removed because the new ActionBeanInfo#setComplementaryStartupLink(boolean) makes more sense.

That’s it! Most of these changes are only breaking changes for corner cases and even then it should be easy to fix them. If you notice any other breaking changes, please let us know, so we can add them to this list.

Offline profiling and triggers

In the screencast below, I explain how to automate profiling with offline profiling and triggers, so that you do not have to use the JProfiler GUI for profiling and can analyze profiling results later on.

Locking graphs in JProfiler

In the screencast below, I present some of the features in the locking graphs that have been introduced in JProfiler 6.

The test class that is profiled in this screen cast is given below:

public class MonitorTest {

// The only monitor that all threads are blocking or waiting on
private static final MonitorTest monitor = new MonitorTest();

public static void main(String[] args) throws InterruptedException {

// All threads execute this runnable, each thread acquires the
// monitor, works for 3 seconds and then waits on the monitor
Runnable runnable = new Runnable() {
public void run() {
synchronized (monitor) {
try {
// Instead of doing any real work, the thread just
// sleeps for 3 second
} catch (InterruptedException e) {


// 3 threads are started with an offset of 500 ms
new Thread(runnable, "Test Thread 1").start();
new Thread(runnable, "Test Thread 2").start();
new Thread(runnable, "Test Thread 3").start();

// After 20 seconds, all threads are woken up and the test class
// terminates
synchronized (monitor) {

Fine-tuning console installers

In the upcoming install4j 4.2.4 release, we’ll expand on the improvements that were introduced with the visibility script in install4j 4.2.3.

The GUI installer operates in a “one screen at a time” mode while the console installer does “one question at a time”. Due to this difference, the automatic translation of form screens from GUI to console mode will not always be optimal.

In 4.2.4 we will introduce a “Console handler” form component that allows you to fine-tune the console mode of your installers. The form component is invisible and has no effect in GUI mode. Its action is defined in the “Console script” property:

Besides the usual parameters for form components, the script is passed a “console” parameter, which is of type com.install4j.api.screens.Console and offers a number of methods for interacting with the user on the console. This has previously only been offered in the API for the development of custom screens and custom form components.

In the console script shown above, an error condition is handled in the middle of the form component sequence. In GUI mode, such error conditions are usually handled in the validation script of the screen, but due to the lack of “screens” in console mode, the validation might be more appropriate at an earlier time.

Another scenario for the use of console handler form components are form screens that do no require user input. In such a case, you could add a console handler form component and set its console script to

console.print("Please read the information above");
return true;

Appending to redirection files

install4j has always offered the possibility to redirect stderr and stdout to files. The main purpose of this feature is to analyze uncaught exceptions and to get debug information when something goes wrong in a customer’s installation.

The redirection files are created lazily, meaning that as long as there is no output, the file will not be created or replaced. However, once output is detected, the redirection file is created or overwritten. This has been the only option so far and while it is often sufficient to retain the error or debug output of the last run, in some cases you might want to keep the entire output over multiple invocations of the launcher.

In the upcoming install4j 4.2.4, we have added this feature and in the redirection step of the launcher wizard, you can change the classic “Overwrite” behavior to “Append”.

The redirection file will still be created lazily, but it will be appended to if it already exists.