Category: install4j

Stricter time-stamp validation on macOS 10.14

Today we released an install4j emergency release for macOS 10.14 that fixes a problem with code signing. Previous versions of install4j used time stamp validation during code-signing in such a way that it’s no longer recognized by macOS 10.14.

Whenever code signatures are invalid, macOS does not report any specific errors, but just informs the user that the archive is damaged and suggests to move it to the trash, like this:

If you use install4j for deploying to macOS, you probably do use code-signing, so we highly recommend to update to install4j 7.0.6 to avoid problems for users on macOS 10.14.

As an added benefit, the new release can scale splash screens under fractional HiDPI on Windows, so they no longer appear to be to small.

Migrating to install4j 7

In nearly all cases, migrating to install4j 7 just means opening and saving your project with the install4j 7 IDE. Nevertheless, there are some considerations with respect to backwards compatibility and a couple of behavioral changes.

  • The minimum supported Java version is now Java 7 up from Java 6 for install4j 6. This also means that the old Java 6 Apple JRE is no longer available as a separate type on the Bundled “JRE” step of the macOS media wizard. The launcher runtime still supports Java 6 and you can set the compiler variable sys.ext.forceMinJavaVersion to true in order to allow “1.6” as a minimum version. Note that no classes in the API can be called from Java 6.
  • The “native splash screen” feature for Windows has been removed. This went back to the pre-Java 6 days when Java did not offer splash screen functionality and was missing several important features. If you had this feature selected for one of your launchers, it now uses the regular Java splash screen
  • When a rollback terminates at a rollback barrier, the exit code of an installer application is now 0. To restore the old exit code of 1, you can set the “Exit code” child property of the “Rollback barrier” property to 1
  • In the “Key validation expression” script property of text components, the “keyCode” parameter has been removed. It was always 0 before and did not serve a useful purpose.
  • If you develop your own screens with the API, the methods isShowIndex, hasTitlePanel, hasDefaultInsets and hasDefaultButtons have been removed from the interface com.install4j.api.screens.Screen and so your existing implementation of these methods will no longer be called by install4j. This functionality is now covered by styles which are much more flexible than the previous limited styling capabilities.
  • In the API, methods with Object[] arguments for variable parameter lists have been converted to varargs. This should not cause source or binary incompatibilities but may show warnings in your code if you call such methods.
  • The “Create a quick launch icon” action has been removed with no replacement. The last OS where it had any effect was Windows Vista.
  • If you have not set a maximum Java version, and do not use a bundled JRE, any installed Java 9 JRE will be used. Java 9 has backward compatibility issues that may prevent your application from working unless you explicitly support it. Consider limiting the maximum Java version to “1.8” in that case.
  • If the “Request privileges” action fails, an installation directory in the user home directory is set. To restore the old behavior of keeping the default installation directory deselect the “Fall back to user specific installation directory” property on the “Request privileges” action.
  • With install4j 7, you cannot use the deprecated com.apple.eawt.Application.Application.getApplication().addApplicationListener(...) in the macOS EAWT API anymore, you have to use the new API methods, for example

    Application.getApplication().setQuitHandler((quitEvent, quitResponse) -> {
    quitResponse.cancelQuit();
    // TODO add your code
    });

    for the quit handler.

If you notice anything else, please let us know!

Comparing install4j to other deployment solutions

Samuel Ruggieri from Voyager Games has written an interesting article comparing install4j against Java Web Start and other installer builders. His conclusion is this:

“At the end of this adventure, I have another experience that demonstrates the old adage that it’s cheaper to buy software than to build it. In this case, it’s cheaper and better. Software engineer hours are expensive, and for a non-trivial Java application, you’ll burn scores of them if you try to build a custom deployment and auto-update solution. At the end of that development, whatever you’ve built will almost certainly be inferior to what install4j can give you with a bare minimum of expense, both in terms of time and effort.”

If you’re thinking about comparing different deployment solutions for your Java application, maybe his article can provide some shortcuts.

Migrating to install4j 6

In nearly all cases, migrating to install4j 6 just means opening and saving your project with the install4j 6 IDE. Nevertheless, there are some considerations with respect to backwards compatibility and a couple of behavioral changes.

  • The minimum Java version for launchers is now Java 6. If your launchers must run with Java 1.4 or Java 5, you have to stick with install4j 5.
  • The minimum Java version for the install4j IDE and the compiler is now Java 7. If your build machine only has Java 6 installed, you have to install a Java 7 JRE. On Windows and Mac OS X, Java 7 JREs are bundled in the install4j downloads.
  • The install4j API has been generified and old-style enums have been converted to language enums. Theses changes are binary and source compatible. The only exception is that enums do no longer extend com.install4j.api.SerializableEnum. In the unlikely case that you use this class in your custom code, you will have to replace it with the actual enum class.
  • Installer variables loaded by the “Load response file” action or the -varfile command line parameter are now automatically registered as response file variables. The eliminates problems with fast-path upgrade installations where response file variables would be lost if their form components were not be shown. If this change impacts on your logic, the “Load response file” action now has a “Register variables for response file” property that you can deselect to revert to the old behavior.
  • By default, the “Load response file” action will no longer overwrite installer variables that have been set explicitly on the command line with the -Vvariable=value option. This is the intuitive behavior and makes installer variables more flexible. If this change impacts on your logic, the new “Overwrite strategy” property of the “Load response file” action can be set to “Do not overwrite existing”.
  • Mac OS X archives are now generated in DMG format. This means that the generated media file name will change between install4j 5 and install4j 6 and you have to adjust download links on your web site. If you would like to keep the .tgz format, you can change the corresponding option on the “Installer options” step of the media wizard.
  • Invisible form components are no longer validated. A validation error would leave the user with no clue what to do, so this was really a mistake in previous versions. However, bound installer variables are set during the validation phase and that will no longer happen for invisible components. If you rely on the installer variables to be defined, you should predefine them in the “Installer variables” section of the installer or custom installer application.
  • Several installer variables that were previously only defined on Windows are now defined on multiple platforms. New cross-platform installer variables are “sys.desktopDir” and “sys.docsDir”. The installer variables “sys.appDataDir”, “sys.localAppdataDir”, “sys.docsDir”, “sys.fontsDir” and “sys.programsDir” are now also defined on Mac OS X. If your code checks if any of these installer variables is null, it may no longer work correctly.
  • The “Reboot computer” action and Context#triggerReboot now work on Mac OS X as well. If you rely on the previous behavior of not doing anything on Mac OS X, this may not be what you want. In that case, you have to add platform-specific checks in your project.
  • The ICNS icon for Mac OS X launchers is now generated from cross-platform images. If you previously had no ICNS icon defined but the “Add icon to launcher” check box was selected, the maximum resolution of your icon files might be too low. You need at least a 128×128 image for the icon to look good on Mac OS X. The old default ICNS icon is still available under resource/macos/app.icns, so you can specify it explicitly to restore the old behavior.
  • The name of the uninstaller on Mac OS X has changed if your project is localized. Previously the file name of the uninstaller application bundle was set to the localized name. In install4j 6, the file name is always set in the principle language and the localization is provided by the application bundle. You will see the localized name in the Finder, but not in the terminal.

If you notice anything else, please let us know!

    The v2 signature scheme for application bundles on Mac OS X 10.9.5+

    Apple has decided to introduce a new signing scheme in the upcoming Mac OS X 10.9.5 maintenance release.

    The good news is that the new signature is much better from a security point of view. The utility of the old signature was highly questionable, because it allowed unsigned and modifiable files in the application bundle. An attacker could change the JAR files in the application bundle and the signature of the application bundle would remain valid.

    The bad news is that all existing signatures are going to break. Only applications with a v2 signature will be accepted by Gatekeeper starting with Mac OS X 10.9.5. On the upside, the v2 signature is backwards compatible with older versions of Mac OS X. The means that if your application bundle is signed with the new scheme it will work in Mac OS 10.8, 10.9 and 10.10 – and hopefully even with future versions of Mac OS X.

    We have implemented v2 signatures in install4j 5.1.13, so you can already create application bundles that will work with the upcoming disruptive releases of Mac OS X.

    However, this change may have consequences for your install4j projects:

    • The application bundle that is installed by a “Mac OS X single bundle” installer cannot be signed anymore. The installer installs variable files into the bundle and of course it cannot update the signature of the bundle. Previously all these files did not influence the signature (you can see that this was a bad idea), but now everything in the bundle must be signed. If you really need a signed launcher, you have to switch to the “Mac OS X single bundle” archive.
    •  Info.plist files and .vmoptions files in signed bundles cannot be changed anymore without breaking the signature. If you rely on the validity of the signature of the application bundle, you have to ensure that these files remain untouched. This applies to single bundle and folder archives as well as to the folder installer with signed launchers enabled.

    To make the correct decisions, you have to understand that a signature is only required for the file that user downloads from the internet. An installer can install application bundles that are unsigned, because those will not be checked by Gatekeeper.

    A signature on an installed application bundle is only required if you need access to restricted services, such as iCloud storage or the notification center. In addition, signed application bundles are treated preferentially in some cases. For example, if the user enables the firewall, unsigned application bundles can only receive incoming connections after the user confirms a question from the firewall.

    Migrating to install4j 5.1

    The following new features in the install4j 5.1 require consideration when migrating from 5.0:

    New architecture for elevated privileges

    install4j 5.1 introduces a new architecture for elevated privileges. Under some circumstances this can create backwards compatibility problems with your existing projects that are discussed below.

    Prior to install4j 5.1, the the “Request privileges” action could restart the entire installer process and run the installer GUI and all the actions with elevated privileges. This was the default setting on Windows and also available on Mac OS X. The unelevated process was kept around only for starting launchers and other executables without privileges. On Mac OS X, the default mode for the “Request privileges” action was to start an elevated helper process that was used internally by some actions – such as the service actions. The strategy of running the GUI without elevated privileges is a lot better, but our helper process had very limited capabilities and so it could not be made the default on Windows.

    Enter install4j 5.1: We have now removed the “restart” and beefed up the elevated helper process considerably. Single actions can now be executed in the elevated helper process. To this end, we have added an “Action elevation type” property to all actions in the install4j IDE. Unless the action declares a different default value, it is set to “Inherit from parent”. The “Action elevation type” is also configurable on screens, installer applications, screen groups and action groups, and determines the default value for the contained actions.

    If an action is set to be executed with maximum available privileges and an elevated helper process has been started by the “Request privileges” action, the action is serialized to the elevated helper process, executed there and then serialized back to the unelevated process. In the elevated helper process, it has access to all installer variables and it can interact with the GUI through the methods in the com.install4j.api.Util class. Elevated actions in console installers can use all methods in the provided com.install4j.api.screens.Console object to interact with the user.

    If you are just using standard actions, migrating to install4j 5.1 should not break anything. If you use custom code, the two-process architecture and the changed default privileges might impact your installer. Here are the points that you should look at:

    • Using static state in elevated actions may have unintended consequences, since static state is not synchronized between the two processes. Only use installer variables for saving state.
    • Elevated actions must be serializable. The base interface for actions now extends java.io.Serializable, but all contained objects must be serializable as well, otherwise a fatal error will occur.
    • Installer variable values should be serializable. If you place a non-serializable value into an installer variable, you will not be able to use it in elevated actions.
    • If your action previously assumed that it would have full privileges, you have to set its “Action elevation type” to “Elevate to maximum available privileges” manually. For example, a “Run script” action that modifies a file with your own code may not work on a file in the installation directory unless you elevate the action. For custom actions, you can call setFullPrivilegesRequired or setDefaultActionElevationType in your action bean info in order to automatically set the correct elevation type in the install4j IDE when the action is inserted.
    • Some methods in the API do not work in the elevated helper process. They have been marked to throw NotSupportedInElevationException in the API javadoc. Mainly this concerns methods in the context that change the control flow (i.e. jump to another screen) or methods that modify the GUI. If your action needs to use these methods while at the same time requiring elevation, you can always use context.runElevated(...) to push a piece of code to the elevated helper process.

     The key advantages of the new architecture are:

    • Unified privileges architecture for Windows and Mac OS X
    • No more problems due to user change on authentication
    • Privileges can reasonably be requested at any point in the installer, not only at the beginning
    • Better desktop integration of the installer GUI, for example for drag and drop

    Support for OpenJDK on Mac OS X 

    OpenJDK is the way forward for Java applications on Mac OS X. However, the following points need your attention:

    • It is not possible to deliver an installer or a single bundle archive that support both the old Apple JRE as well as OpenJDK. The stubs are different and you choose either option in the media wizard. Old projects will keep the Apple JRE option, so nothing will change by default
    • JRE bundling on Mac OS X is only supported for Open JDK
    • The minimum Java version for OpenJDK is Java 7 and the minimum Mac OS X version is 10.7.3. So you can currently target only newer systems and only if your application supports Java 7.

    Code signing for Windows and Mac OS X

    Code signing on Windows and Mac OS X is now implemented in pure Java code which works on any supported platform. Previously, install4j only offered a hook for inserting an external code signing tool for Windows which would be executed for each launcher and installer application. This functionality is still available for Windows media files and is now called “Executable processing”. So your existing solution for code signing will still work and there is no immediate need for action.

    However, if you have .pvk and .spc files for your code signing certificate, you can enter them on the General Settings->Code Signing tab and enable Windows code signing there. You then have to remove the external code signing command on the “Executable processing” step of the media wizard.

      Beyond installing

      In the two last articles, I showed how to build an installer with install4j for Sweet Home 3D, then improve it with various options. But a program lives, and more and more users are used to getting program updates automatically. As install4j includes an auto-update feature, I’m going to use it to update Sweet Home 3D when a new version is released. Finally, I’ll provide all the nice options that install4j offers for Mac OS X and Linux users by creating a cross platform installer.

      Auto-updating

      install4j offers various ways to check whether updates are available and to manage the launching of the updater. As I want to provide auto-updating without modifying the Sweet Home 3D source code at this moment, I’m going to set options in install4j that will check if a new version of the program is available when the program is launched. The auto-update feature is informed about the availability of a new version thanks to an updates.xml file I’ll have to host at a specified URL. Each time an installer is built, install4j creates a default updates.xml file in the output directory, and when a new version will be available, I’ll just have to upload that file along with the new version of the installer. For the version 3.0 of the installer, this file looks like this:

      <?xml version="1.0" encoding="UTF-8"?>
      <updateDescriptor baseUrl="">
      <entry targetMediaFileId="80" updatableVersionMin="" updatableVersionMax=""
        fileName="SweetHome3D-3.0-windows.exe" newVersion="3.0" newMediaFileId="80"
        fileSize="27361280" bundledJre="windows-x86-1.6.0_23" archive="false">
      <comment language="en" />
      <comment language="zh_CN" />
      <comment language="cs" />
      <comment language="fr" />
      <comment language="de" />
      <comment language="el" />
      <comment language="hu" />
      <comment language="it" />
      <comment language="ja" />
      <comment language="pl" />
      <comment language="pt_BR" />
      <comment language="ru" />
      <comment language="es" />
      <comment language="sv" />
      </entry>
      </updateDescriptor>

      To prepare future updates, I have to decide in this version where I’ll host the updates.xml file. Thus, I enter the URL “http://www.sweethome3d.com/download/updates.xml” in Auto-Update Options tab of the Installer screen.

      Then, in the Screens & Actions tab, I click on the Insert button and select the Add Application menu item.

      In the Select an Application Template dialog box, I select the Updater with silent version check template.

      Once I click on OK, a new node is added to Installer screen for the updater application and I name its Executable as “SweetHome3DUpdater” in its Properties tab.

      To run this updater automatically when Sweet Home 3D or Furniture Library Editor are launched, I click on the Launcher Integration tab, select the Start automatically when launcher is executed option and choose to Always run the updater.

      Minimum auto-updating is now integrated and I just have to build a new installer to make it available for a future version of the program.

      To test it, I immediately install version 3.0 of the program, generate an installer with a fake 3.0.1 higher version number,

      and upload SweetHome3D-3.0.1-windows.exe and updates.xml to http://www.sweethome3d.com/download after adding a small comment in default language to updates.xml file.

      <?xml version="1.0" encoding="UTF-8"?>
      <updateDescriptor baseUrl="">
      <entry targetMediaFileId="80" updatableVersionMin="" updatableVersionMax=""
        fileName="SweetHome3D-3.0.1-windows.exe" newVersion="3.0.1" newMediaFileId="80"
        fileSize="27427328" bundledJre="windows-x86-1.6.0_23" archive="false">
      <comment>Fixed minor bugs</comment/>
      </entry>
      </updateDescriptor>

      Then, a few seconds after I launch Sweet Home 3D version 3.0, the updater is launched and offers to download Sweet Home 3D version 3.0.1.

      If I click on the Show comments link, I get the comments entered in the updates.xml file.

      Otherwise the download of the new version is started.

      Once downloaded, I choose to execute the downloaded installer.

      Because the installer detects that a previous version is installed on my computer, it asks me whether to update or to install it in another location before performing the installation.

      Managing cross platform installers

      Since install4j is a Java program itself, it’s easy to prepare installers for each operating system where JVMs are available. If an application shares the same list of files (which is generally the case), I would just have to create a different media for each targeted operating system with its dedicated JRE. It’s a little more complicated for Sweet Home 3D since it requires different Java 3D DLLs for different platforms. Therefore, I download Java 3D zip binaries for Mac OS X, Linux 32 bits and Linux 64 bits at Java 3D release builds page. Each of these zipped files contains a j3d-jre.zip file, and each j3d-jre.zip file contains the three j3dcore.jar, vectmath.jar and j3dutils.jar files which are the same as the Windows ones I have already, plus some DLLs like libj3dcore-ogl.so under Linux that I have to keep. Under Mac OS X, Java 3D works thanks to JOGL library, that I download too.
      Once I retrieve all these files, I copy the ones required by Java 3D in a lib subdirectory of Install directory and reorganize them to avoid any name conflict.

      These files will have to be copied in the lib subdirectory of the destination directory where program will be installed. To copy only the Java 3D files required for a given operating system, I’m going to create one file set for each system in install4j. In the Files screen, I click first on the Insert button and choose the New File Set option.

      I enter the general name “Windows“,

      and renew the New File Set operation for Mac OS X, Linux 32 bits and Linux 64 bits.

      Then, for each of these file sets, I create a new lib folder by clicking on the Insert button and choosing the New Folder option.

      Once the lib subdirectories are ready, I select the one in Windows file set, click on the Insert button and choose Add Files and Directories option.

      In the Add Files and Directories dialog box, I choose the Single files option,

      click on the Next button, and select the four Java 3D DLLs for Windows in C:Program Files (x86)Sweet Home 3D 3.0lib directory.

      I confirm my choice, and repeat the same operation to add the Java 3D files that depends on Mac OS X, Linux 32 bits and Linux 64 bits.

      To get consistent file sets, I also have to remove the Java 3D DLLs from Default file set: I select the Content of C:Program Files (x86)Sweet Home 3D 3.0lib into subdirectory lib node, click on the Edit Entry button,

      and in the Modify Entry in the Distribution Tree dialog box, I change the entry type to Single files and select all the files in C:Program Files (x86)Sweet Home 3D 3.0lib directory except the four DLLs.

      Once I chose these JAR files, I move them to the lib subdirectory of the installation directory.

      Finally, I click on the Installation Components tab, select the Sweet Home 3D component and include Windows, Mac OS X, Linux 32 bits and Linux 64 bits file sets.

      Now that file sets are ready, I’m going to use them in the Windows existing media file and in the new media files for Mac OS X and Linux. I go to the Media screen,

      and double-click on the Windows media file to exclude the file sets that are not needed for Windows.

      Then, I click on New media file icon to create Linux 32 bits media file. In the Installer type combo box, I choose Unix/Linux GUI installer,

      and click on the Next button until the Data files step where I enter the same download URL http://ovh.dl.sourceforge.net/project/sweethome3d/FurnitureLibraryEditor/ for the Furniture Library Editor as I did for Windows media.

      In the Bundled JRE step, I click on the Download JREs button,

      to download Linux (x86) 1.6.0_23 JRE.

      Once downloaded, I choose this JRE,

      customize the installer by setting the media file name to “${compiler:sys.shortName}-${compiler:sys.version}-linux-32bits

      and by excluding the file sets of the other operating systems.

      Once the Media wizard is finished for Linux 32 bits, I create similarly the media file for Linux 64 bits, and rename them as Linux 32 bits and Linux 64 bits with the Rename Media File menu item available in their contextual menu, to be able to distinguish more easily.

      Mac OS X installer is very similar to the other installers except it doesn’t need to download a JRE and it requires an additional VM option to run: as Mac OS X provides its own JRE with the Java 3D 1.3.1 library in extension directory, I have to change the java.ext.dirs system property to ensure the Java 3D 1.5.2 library installed with Sweet Home 3D will have a higher priority. To set this VM option that should replace the -Djava.library.path=lib existing one, I create the java3dDllsVMOption compiler variable by clicking on the Insert button in the Compiler Variables tab of the General Settings screen and enter “-Djava.library.path=lib” as its default value.

      Then in the Java invocation step of SweetHome3D launcher, I update the text of the VM Parameters field with ${compiler:java3dDllsVMOption}.

      Finally, I click on New media file icon, choose Mac OS X folder Installer type,

      update the download URL, exclude the file sets of the other operating systems and in Compiler variables step, override java3dDllsVMOption variable with the value
      -Djava.ext.dirs=lib:/Library/Java/Extensions:/System/Library/Java/Extensions:
      /System/Library/Frameworks/JavaVM.framework/Versions/1.5/Home/lib/ext

      I can now build the 4 installers and test them on each operating system.

       

       

       

      Conclusion

      install4j offers many options to help with auto-updating installed software and to deliver Java cross platform installers and uninstallers. install4j can create installers for all supported platforms on any supported platform, so on a Linux build server you can create installers for Windows and Mac OS X as well.

      More installation options with install4j

      Last week, I explained how to build an installer with install4j for Sweet Home 3D, that would behave as the one distributed on the web site of the program.

      But Sweet Home 3D and install4j provide some options that could be nice to offer to end users at installation time like:

       

      • keeping the language chosen at installation as the default language of the program,
      • configuring the max memory amount used by the program from the RAM available in the computer,
      • offering to download and install an optional program like the Furniture Library Editor,
      • downloading some optional files like archives containing 3D models,
      • offering special options when the program is installed on a USB key,
      • offering to delete program and configuration files during uninstallation,
      • translating the text of the special options added to the installer,
      • installing the program in unattended mode to speed up its deployment in
        schools.

       

      Storing the chosen language

      In Sweet Home 3D, the user may change the language used in the graphic interface with the preferences panel displayed when he selects the File > Preferences menu item. The persistence of his choice is managed with Java Preferences class which stores its values in the registry under Windows. install4j offers an action able to set the value of a Java preference and I’m going to use it to store the language used in the installer.

      As I want this action to occur after files were installed, I select Installation node in install4j and choose Add Action in its contextual menu.

      I type the the first letters of “preferences” in the Filter text field and select the Set a key in the Java preference store action among the 5 actions dealing with preferences.

      Once I click on OK, I fill the Java preference properties of the action from the matching value read in Sweet Home 3D. I set Package name value to “com.eteks.sweethome3d.io” and Key value to “language“.
      The value of the Value text field must be set according to the language currently used in the installer, something stored in one of the install4j variables. To find it out, I click on the button arrow at the right of the text field and select the Insert Installer Runtime Variable option.

      In the Select Installer Runtime Variable dialog box, I filter variables with the first letters of “language” and choose sys.languageId variable.

      Finally, I choose User specific for Preference root field.

      Configuring the max memory of the program

      Sweet Home 3D may require a lot of memory in some circumstances, and the default amount of maximum memory used by a Java Virtual Machine is generally not enough to let the program work correctly for big layouts. At the opposite, if too much memory is required, the program may slow down too much because the operating system will have to manage the missing RAM with disk swapping. A nice option could be to fix the maximum memory used by the JVM by program according to the available physical memory. This amount of memory is passed to the JVM with the option -Xmaaaam where aaaa matches the maximum memory in MB.

      I already set -Xmx to 512m during the configuration of a launcher by setting the VM parameters value at the fourth step of the launcher creation wizard.

      To set this value according to the memory available on the end user computer, the easiest way is to remove the -Xmx512m option from VM parameters and add an action to update VM parameters when the installer is run. As this action should happen at the end of the installation, I select the Installation node, click on the Insert button (the button with a green plus) and select the Add Action menu item.

      In the Select an Installation Action dialog box, I choose the Add VM Options action,

      and once I click on OK, I edit the properties of the action to set SweetHome3D as Launcher value and enter the text “${installer:xmx}” in VM options text field.

      This value references the installer:xmx variable that will be evaluated at installation time, when the installer will be run. As I need to create this variable and give it a value, I click again on the Insert button and select Add Action menu item. This time, I choose the Set a variable action in the Select an Installation Action dialog box.

      Once I click on OK, I move the new action one row up before the Add VM options action by clicking on the blue up arrow, edit the properties of the action to set the “xmx” name of the new variable without its installer prefix, and click on the button with an ellipsis at the right of the Script text field to edit its value.

      This opens a text editor where I have to enter a Java expression whose value will be saved to the xmx variable.

      The comment displayed by the editor suggests I can use the two context and action parameters if required, and the classes of these two parameters are com.install4j.api.context.InstallerContext and com.install4j.api.actions.InstallAction shown as hyperlinks to their respective javadoc pages.

      The great thing is that editor offers auto completion when I press Ctrl + space keys! For example, if I try to complete “co” I’ll get “context” at the top of the suggested items and other items starting by “co“.

      I choose context, type a dot to invoke a method of the InstallerContext class, but there are so many choices that it’s quite difficult to find out the method that returns the memory available in the computer where the installer runs (this value isn’t available in Java SE 6 too).

      Therefore I explore the help file, which seems pretty complete, since I find the information I need with a search of the “memory” keyword which brings me to the method getPhysicalMemory in the com.install4j.api.SystemInfo class.

      As this method is static, I finally enter the expression
      "-Xmx" + (SystemInfo.getPhysicalMemory() / 2 / 1024 / 1024) + "m"
      and as the green square drawn at the end of line confirms, the syntax of my expression is correct,

      I click on OK, save my install4j project, build it and run the installer to check how it works.

      As setting this option won’t change anything at the screen, I run SweetHome3D.exe executable file in a command window with the option /create-i4j-log that will create a temporary log file. To help me to find this log file, install4j displays an information dialog box recalling where it can be found.

      Reading this file I can see a vmoption line with -Xmx755m option stating the half of the 1.5 GB memory of my computer might be occupied by the Java program.

      Downloading an optional program

      A program called the Furniture Library Editor was recently added as a separate application. It allows the user to import and edit faster the attributes of a group of 3D models instead of importing them one by one in the program.

      This program is a Jar executable application and I want to suggest it as an option in the installer. As it is around 5 MB large, it won’t be bundled with the installer but downloaded if the user wants to install it.

      To make it a downloadable file, I have to add it to the installer Files and then select it as a downloadable component in the Media wizard. Therefore, I download FurnitureLibraryEditor-1.2.jar in the Installer directory on my desktop, and add it to the Installation directory node in the Files screen as a single file with the Insert button (the button with a green plus).

      Then I create a new launcher for the Furniture Library Editor as I did for Sweet Home 3D, by clicking on the New launcher icon in Launchers screen.

      This time, I name the executable file as FurnitureLibraryEditor, select the Allow only a single running instance of the application option,

      fill the windows version info resource,

      configure its icon in the Icon step,

      configure program launch by adding FurnitureLibraryEditor-1.2.jar archive in class path and using com.eteks.furniturelibraryeditor.FurnitureLibraryEditorBootstrap as main class,

      and no splash screen. I finally see the new laucher item in install4j.

      To make FurnitureLibraryEditor-1.2.jar and its launcher optional files, I then click on the Installation Components tab to create components that group files by application. I click on the Insert button, enter first the name of the basic component that will contain the Sweet Home 3D application files and click on OK.

      In the Files tab, I select all the files except FurnitureLibraryEditor-1.2.jar and its launcher,

      Then I create a second component for the FurnitureLibraryEditor-1.2.jar file that will be downloaded.

      In the Options tab of that component, I unselect Initially selected for installation option and select Downloadable component

      As the launcher of the Furniture Library Editor won’t be downloaded but will be bundled with the installer (launchers are small files of 250 KB), I create a third installation component named Furniture Library Editor launcher for it, select [Launcher] FurnitureLibraryEditor file and change the options to hide it to the end users, because it would be useless to ask them to check two options if they want to install the Furniture Library Editor.

      Now that installation components are created, I go to the Installer screen and select the Installation components node, that will be displayed from now on since I created installation components.

      As I need to select the Furniture Library Editor launcher component if the Furniture Library Editor component is selected by the user, I click on the ellipsis button beside Selection change script field and enter the matching Java statement

      Each component, screen or action in install4j has a unique ID and I need to find the ID of the Furniture Library Editor launcher component to pass a correct value to getInstallationComponentById method call. The IDs of install4j items can be displayed by clicking on the Show IDs button found on many screens, but to avoid closing the editor window, I prefer here to click on the Insert ID button to find the desired ID. This will open a dialog box where I enter the first letters of “Furniture” and find the ID of the component is 376.

      I click on OK to close the script window, and finally go to the Media screen to update the Windows media file

      that requires to be completed with the URL http://ovh.dl.sourceforge.net/project/sweethome3d/FurnitureLibraryEditor/ where FurnitureLibraryEditor-1.2.jar can be downloaded from.

      I build a new installer and test it. A new step is now displayed that will let me choose what I want to install.

      I select the Furniture Library Editor option and check that the new application is available in Sweet Home 3D group.

      Downloading other optional files

       

      Sweet Home 3D lets the user import pieces of furniture one by one, but also by group of pieces from .sh3f files (that the Furniture Library Editor can edit). At this time, four .sh3f files are available to download 400 models separately, but I’m going to offer them as optional files during installation time.

      The 4 files to download are these ones:

       

      Once downloaded, these files should be unzipped in a private directory of Sweet Home 3D that depends on the target system. Under Windows 7 and Vista, it should be under the directory C:UsersuserAppDataRoamingeTeksSweet Home 3Dfurniture and under previous versions of Windows C:Documents and SettingsuserApplication DataeTeksSweet Home 3Dfurniture, where user is the user’s login name.

      This time, unlike during the previous part where I installed an optional program, I’ll create an Installation Components associated with no files, then use the Download file and Extract a ZIP file actions.

      Thus, I create four additional Installation components in the proper tab of the Files screen. To simplify the way to find them later, I create a custom ID for each of them with a value equal to its name.

      Then I unselect the Initially selected for installation option and select the Downloadable component option for the 4 new components.

      To manage the download of the optional files, I go to the Installer screen, select the Installation node and insert a Download file action.

      In the properties of the Download file action, I set the URL to “http://ovh.dl.sourceforge.net/project/sweethome3d/SweetHome3D-models/3DModels-1.1.1/3DModels-Contributions-1.1.1.zip“, the Target file to “${installer:sys.workingDir}/3DModels-Contributions-1.1.1.zip” and select the Delete downloaded file on exit since it won’t be needed once unzipped.

      Then I click on the ellipsis button beside the Control Flow / Condition expression field to enter the condition when this action should be executed

      To unzip the downloaded file to the right directory, I insert a Extract a ZIP file action after the Download action.

      In the properties of the Extract a ZIP file action, I set the Zip file to “${installer:sys.workingDir}/3DModels-Contributions-1.1.1.zip” and enter a File filter script condition that will extract only files ending with .sh3f.

      I enter “${installer:privateDir}furniture” in Destination directory field because the place where the application configuration data is stored varies from one operating system to the other, and set the value of the privateDir variable with a new Set a variable action, setting its script to the corresponding
      method in Sweet Home 3D.

      Finally, I move the Set a variable action two rows up and I create the same Download file / Extract a ZIP file actions for the 3 other optional downloads. Installation screen runs 20 actions now!

      Once built, the new version of the installer displays the options to download the optional files,

      and if I check some of them, it will download them.

      Setting special options

      From the previous parts, you understood that like many other applications, Sweet Home 3D stores its configuration data in private directories. But some users want to be able to move an application and its configuration around without bothering how to copy this data, and requested to make Sweet Home 3D portable (not across operating systems, but across different computers). This ended up by the new com.eteks.sweethome3d.preferencesFolder and com.eteks.sweethome3d.applicationFolders system properties that give the directories where Sweet Home 3D will store its configuration data.

      To spare end users the difficulty to set these properties, I’m going to add a new screen shown after the Installation location screen where the user will be able to choose whether he wants to install Sweet Home 3D as a portable application or not, when he chose a removable drive as installation destination.

      To create this customized screen in install4j, I select the Installation location node in Installer screen, click on the Insert button and choose Add screen option.

      In the Select an Installation Screen dialog box, I choose the Configurable form item in the list of screens  and check Insert after selection at the bottom of the dialog box.

      Once I click on OK, the new screen is added in the Installer screen sequence.

      I click first on the Configure Form Components button to add a check box to the empty form. In the dialog box that appears, I click on the Insert button and choose the Add Form Component option.

      This will open another dialog box in which I can choose among more than 30 different components. I choose a Check box component,

      and click on OK. In the properties list of the inserted check box, I enter “Install as a portable application” as the text check box, enter “portable” as the variable name associated to this check box and select the Initially selected and Request focus check boxes.

      As this new option isn’t so easy to understand, I click on the ellipsis button of the Help text field and enter a text that explains this option,

      and click on OK. Then, I click on the Preview Form button at the top right of the dialog to check how the check box and its help text will be shown.

      This looks nice but the screen title and subtitle are still missing! I close the Configure Form Components and click on the Properties tab of the Configurable form node,
      where I enter “Removable drive option” in Screen title text field and “Should application installation be portable?” in Screen subtitle text field.

      As this screen should be displayed only if the user chose a removable drive, I finally click on the ellipsis button of the Condition expression property to enter the condition.

      As this condition can be checked only under Windows I check first if the installer is running under Windows with a call to Util.isWindows(), then I use the getDriveType method of the WinFileSytem class to check if the installation directory chosen by the user is removable or not.

      The new screen is now configured, and I have to use the value of the portable variable bound to the check box to configure Sweet Home 3D accordingly on the installation screen. As this variable won’t exist if the new screen isn’t displayed, I predefine it by clicking on the Installer node, then on the Configure Predefined Installer Variables button in the Installer Variables tab.

      In the Edit Installer Runtime Variables For “Installer” dialog box, I click on the Insert button and choose the Add New Predefined Installer Variable option.

      I set the name of the new variable as “portable“, set its type to Boolean and its default value to false.

      I click on OK and use the portable value in the Installation node to add new VM options that will set the desired system preferences: I select the Set a variable action that defines the privateDir variable to add this new action after it, click on the Insert button, select Add Action option and choose the Add VM options action.

      I confirm my choice, select SweetHome3D launcher, enter the two lines
      -Dcom.eteks.sweethome3d.preferencesFolder=${installer:privateDir}” and
      -Dcom.eteks.sweethome3d.applicationFolders=${installer:privateDir}” in its VM options text field, and set its condition expression as “context.getBooleanVariable("portable")

      These options reference the variable privateDir whose value must take into account the value of the  portable variable, too. Therefore, I select the Set a variable action that defines the privateDir variable and click on the ellipsis beside its Script field to update it.

      While editing this script, I got the context.getVariable("sys.installationDir") Java expression that returns the value of the sys.installationDir install4j variable by clicking on the Insert Variable button, chosing Insert Installer Runtime Variable item and selecting the sys.installationDir variable.

      I build this updated configuration and try the new version of the installer that displays the new screen if I choose to install it on a USB key.

      Uninstalling a program and its configuration data

      Sweet Home 3D stores user preferences and configuration data in private directories to help users to upgrade the installed version of the software without losing data. But sometimes some users want to really remove all information bound to the installed software. Installers built with install4j are highly configurable, and their uninstaller counterpart is as much configurable as the installer, so I’m going to add a screen that will ask the user whether he wants to delete Sweet Home 3D private files or not, and add some actions that will handle his answer.

      I select the Uninstaller node in Installer screen, click on the Insert button, select the Add Screen option and choose the Additional confirmations screen.

      Once I click on OK, I move the  Additional confirmations screen after Uninstall Welcome screen with the blue arrow button, and click on the Configure Form Components buttons.

      In this form, I’m going to add a check box to confirm the deletion of Sweet Home 3D private data:

      I click on the Insert button, select the Add Form Component option and choose Check box among the list of components.

      I enter “Sweet Home 3D private data” as the displayed Text,

      and click on the ellipsis beside Help text field to detail what will be deleted.

      Finally, I enter “privateData” in the Variable name text field associated with this check box.

      I close the Configure Form Components dialog box and click on Unistallation node to add a new action to it.

      I filter the actions list with “delete” and choose the Delete a node or key in the Java preference store action.

      I enter the “com.eteks.sweethome3d” package in the properties list, unselect the Only if empty check box and let the Key field empty to delete all the preferences associated to this package node.

      I click on the ellipsis beside the Condition expression field, insert the value of the privateData variable to check the condition, and confirm my choice.

      To delete private files, I add a Delete files and directories action to Unistallation node with the same Condition expression and select the Recursive option.

      The files to delete are in the directory referenced by the privateDir variable created at installation time, but I need it also at uninstallation time. Like privateData variable, the value of an installer variable is available in the uninstaller if it’s predefined in the installer and marked as a response file variable. A response file is a properties file that contains key-value pairs for installer variables. This file is created during installation process and is reused during uninstallation.

      All the variables bound to a form component like the portable variable bound to the Install as a portable application check box, are automatically saved in a response file. But the privateDir variable isn’t bound to any component, and I have to define it as a predefined variable and register it as a response file variable.

      Thus, I click on the Installer node, select Installer Variables and click on the Configure Predefined Installer Variables button.

      I click on the Insert button, select the Add Predefined Installer Variable option and enter the name “privateDir“.

      I confirm my choice and add a new Run script action to the Startup node

      that will register the privateDir variable as a response file variable.

      Finally, I select again the Delete files and directories action, and complete its Files and directories field by clicking on the ellipsis button beside it. In the Edit Files dialog box, I click on the Insert and edit the file name by clicking on the arrow button to select the installer privateDir variable.

      Once done, I can build the media files to test the installer and uninstallers.

      When I uninstall Sweet Home 3D, I’ll get a new screen showing the additional option.

      If I check the option, all the configuration data is deleted as expected.

       

      Translating new options

      Some texts in the screens and the options added during the two previous steps aren’t predefined in install4j, and I’ll have to translate them. Handling translation in install4j works similarly to Java with properties text files where each translated text is associated to a key. The differences in install4j are that it’s not mandatory to add a language suffix to each translated properties file and these files can be saved in UTF-8 encoding if they use utf8 file extension (until Java 6, Java properties file supported only ISO-8859-1 encoding which forces you to write characters that don’t exist in this encoding with uxxxx sequence).

      The properties files used by the installer are defined in the Languages tab of the General Settings screen of the installer project, and after clicking on the New button beside Custom localization file field, I choose to name it “InstallerTranslation.utf8“.

      Once I click on the Create button, a text editor is opened to let me define some properties or override existing ones in the installer. I close the editor and prefer to add the properties one by one, by editing the texts to translate where they are defined in the project. In the Installer screen, I select the Configurable form node and in its Properties tab, copy to the clipboard the text of the Screen title field, click on the arrow button beside it and select the Insert I18N Message option (I18N means Internationalization, the 18 number matching the the number of letters between the first and the last letter of this long word).

      In the Select I18N Message dialog box, I click on the Edit link to enter a new key/value pair in the InstallerTranslation.utf8 file.

      I enter the text “portableScreenTitle=Removable drive option” in the editor,

      click on OK, and select the new key that appears in the Custom messages list.

      Once done, the text of the Screen title field is replaced by ${i18n:portableScreenTitle}.

      I perform the same operation for the other 5 new texts that need to be translated.

      The two Help texts are replaced by clicking in the Insert Variable button shown in their editor and choosing the Insert I18N Message option.

      Once done with the InstallerTranslation.utf8 file, i just have to translate this file in each supported language and add them on the Languages tab of the General Settings screen. For example, I can translate the texts to French in a file InstallerTranslationFrench.utf8 and add it to project.

      Installing a program in console or unattended mode

      Installing a program with a graphic user interface is nice for most users, but many environments offer only a command line interface. install4j offers such a mode without any additional change to the installer:
      instead of answering questions with buttons, text fields and check boxes, the end user just uses the keyboard to answer. The console mode is used when the argument -c is passed to the installer program. Under Windows XP / Vista / 7, Sweet Home 3D installer can be run with the following command:

      start /wait SweetHome3D-3.0-windows.exe -c

      which will give the following results.

      install4j offers also an unattended mode, something that may be very handy when you have to install a program the same way on different computers. In that mode launched with a -q argument passed to the installer program, the installation runs by itself until the end without asking any questions. The directory where the program should be installed can be specified with the -dir argument and the answers to the installer questions that should be different from their default values can be specified in a response file by passing the -varfile argument.

      The easiest way to generate such a response file is to run the program in another mode and retrieve the response.varfile file created by the installer in the .install4j subdirectory of the directory where program was installed. This file is a text file that contains installer variables and their values that may be edited with any text editor if needed. Under Windows XP / Vista / 7, Sweet Home 3D can be installed in unattended mode with the following command:

      start /wait SweetHome3D-3.0-windows.exe -q -varfile response.varfile

      Conclusion

      install4j lets you customize your installer in many ways. You can configure it to install some optional items and perform some special operations. You can also use your Java skills to program customized conditions or any required piece of code, in an editor that supplies the great features of modern IDEs.

      My first try with install4j

      A tutorial for beginners

      This tutorial shows the various features offered by install4j 5.0 through the step by step configuration of an installer for Sweet Home 3D, a free open source Java program (so you can reproduce these steps if you want to).

      In its current version 3.0, Sweet Home 3D may be installed with Java Web Start or its own installer (built with Inno Setup and launch4j tools under Windows). But install4j is able to build much more powerful installers and Java launchers than these free products.

       

      Downloading and installing install4j

      install4j can be downloaded from this page. If you want to test it before buying a license you’ll have to fill this form to receive an evaluation key.

      install4j is available for various operating systems and is available in two versions for each operating system, depending on whether you have already installed a JRE 6 on your computer.

      From the previous matrix, I download the Setup Executable (21 MB) for 64-bit Windows and double-click on the installer icon once the file was downloaded.

      Installing install4j already gives an idea of its abilities because the installer was of course built with install4j itself. Once the installer launched, I’m surprised to get a screen telling that no JRE is installed on my computer:

      But in fact the installer was right, I didn’t have a 64-bit JRE but only a 32-bit JRE! Therefore I click on Download to get a 64-bit JRE.

      From the license agreement, installation directory selection to license key entry and auto-update configuration, the 10 steps that following look familiar compared to other installers.

      Launching install4j

      At first launch, Windows Firewall asks me to let install4j use the network to check its license key. I accept to ensure all features of install4j will work.

      Then the main screen of install4j appears and shows the various features offered to create an installer.

      Now I’ll try to create a first version of an installer and launcher for Sweet Home 3D.

      General settings

      First, I fill the Application Info tab with the software’s name and version.

      Then, in the Java Version tab, I require a minimum Java version 1.5.

      In the Languages tab, I keep English as the principal language and add all the languages supported by Sweet Home 3D found in the list (just missing Bulgarian and Vietnamese).

      In the Media Files Options, I choose an Installer directory on my desktop as output directory, change the name pattern to “${compiler:sys.shortName}-${compiler:sys.version}-${compiler:sys.platform}” in respect to the format previously used for older versions of Sweet Home 3D, and uncheck Convert dots to underscores option.

      Note that this name pattern uses some variables between ${ and } symbols. There are all kind of variables available in install4j (you can even create your own if needed) and you can select them in many text fields by clicking on the Insert variable button (the arrow button) that appears behind them.
      The “${compiler:sys.shortName}-${compiler:sys.version}-${compiler:sys.platform}” pattern will resolve to SweetHome3D-3.0-windows for a Windows installer.

      As Sweet Home 3D’s current distribution is around 30 MB, I prefer the smallest distribution possible and I also increase Compression level to 9 and check all the compression options

      Once General Settings are done I save my Installer project in the Installer directory of my desktop.

       

      Files

      Now I choose files that should be included in the distribution by clicking on the Files icon below the General Setting one. These files could be assembled by invoking the appropriate Ant target in the build.xml file of Sweet Home 3D project, but as this tutorial isn’t about Ant, I prefer to use the files installed by the existing setup program available here. I launch this program and install the files in C:Program Files (x86)Sweet Home 3D 3.0 directory.

      Once the existing installer finished, I have to include the jar and license files in the distribution tree of install4j. These files are indicated in blue in the following list:

      Clicking on the Insert button (the green plus button), I choose the Add Files and Directories option,

      and choose the Directory  entry type for the C:Program file (x86)Sweet Home 3D 3.0lib directory with the option Add to subdirectory selected, then Single files type for the licenses files.

       

       

      I also have to include the javaws.jar file found in the jre6lib subdirectory and required by Sweet Home 3D to run. I insert this file as as a Single file type and to make it appear in the lib subdirectory among other jar files, I insert a new folder named lib where I drag and drop the javaws.jar line.

      All these files and directory finally appear in the list of the Define Distribution Tree tab.

      Launcher

      As I don’t need to set any File options or don’t want to propose optional files at this moment, I now click on the Launchers icon below the Files one, and double click on the New launcher icon.

      This will launch a wizard used to create a launcher. As I want to generate a new launcher to test install4j features, I keep the Generate launcher option selected.

      Then I give application name and the directory where it should appear. The Executable info second step offers also an interesting option that allows only a single running instance, that I would check if I didn’t program already such a feature in Sweet Home 3D.

      In the Advanced Options list, I choose Windows version info and check the Generate version info resource to get correct values in the file properties dialog box of the future launcher. I let install4j replace Product name and File version fields and enter values in Internal name, File description and Legal copyright text fields, using some existing variables.

      The Icon third step proposes to choose an icon for the program. I select Add icon to launcher option, and configure the program icons at 3 different sizes and add them to the Cross-Platform Image File list.

      The Java invocation steps shows information required to run a Java application. In VM Parameters, I increase the maximum memory to 512 MB and specify where Java 3D DLLs are available with the parameters -Xmx512m -Djava.library.path=lib (DLLs directory can be set with Advanced Options > Native libraries too). I enter program main class com.eteks.sweethome3d.SweetHome3D and enter -open in Arguments text field because Sweet Home 3D expects this selector before any file passed as an argument.

      Now I need to complete the Class path list, which accepts individual jar files, directories containing jar files, directories containing .class files or resources, and information from environment variables. As I keep all the jar files in the lib subdirectory, I click on the Insert button, select the Scan directory option and enter lib directory.

      The VM options file step offers an interesting option to the end users who can change default VM parameters in case they need it. As Sweet Home 3D uses a few System properties and may require more memory to run, I keep the default Copy template file with explanations for user selected.

      Finally, in the Splash screen step, I can choose the splash screen image that should be displayed during program launch. As Sweet Home 3D handles this feature itself, I don’t change default settings but note that you can use install4j splash screen or Java 6 one if needed.

      The Advanced options let you even write some texts over the image. Nice!

      Once the Launcher wizard is finished, a new launcher icon is added to Launchers screen to let you change launcher settings later.

      Installer

      The Installer screen describes the various screens that will be displayed to the end user during program installation and uninstallation. It’s a highly configurable tool with many options that you can even extend if needed. The screens in the default template will show six screens from Welcome screen to Finish screen.

       

      In the Screens & Actions tab, these screens are represented with an icon showing a gear in a window and sometimes by custom icons like the one used for the Installation screen . The tree shown on the left contains also some actions represented with a gear icon window and by custom icons like the one for the Startup action . An action is simply one or more statements (either preprogrammed ones or custom ones programmed in Java) that the installer should run during the installation.

       

      To ensure the installer created with install4j behaves as the existing one, I’ll add two screens:

       

      • one displaying the GNU GPL license of the software,
      • one that will let the user accept file associations,

       

      and I’ll add also two types of actions:

       

      • some registering file extension associations,
      • one that will let the user launch Sweet Home 3D once the installation is finished.

      To add the new screens, I click on the Insert button and choose Add Screen in the popup menu.

      In the displayed Select an Installation Screen dialog box, I filter the shown list by entering the first letters of “license“. Once I select Display license agreement item, I definitively know that screen has some good chances to be the one I look for from its Description displayed below.

      I click on OK and the new screen is automatically inserted after the Welcome screen, just at the right place I wanted it to appear!

      I now enter missing values in the screen properties list displayed at the right. I edit the License file property and install4j lets me choose it either as a file packaged with the installer or coming from installed files.

      I choose the first option and select the COPYING.TXT file that contains the GNU GPL license text. As the license wasn’t translated to other languages, I leave the file empty for the other languages, so the default text in English will be displayed.

      Then I select the User must scroll to bottom option in the hope it will get more users to read the GNU GPL license.

      I click again on the Insert button to add a File associations screen and select File associations item in the Select an Installation Screen dialog box.

      Once I click on OK, install4j warns me that the File associations screen requires one or more File association actions to work.

      I close the warning message. The File associations screen is added between Create program group and Installation screens, and I check Show selection buttons property to speed up user choice. As Sweet Home 3D has 5 file associations, these buttons will let him or her to select or deselect them with one click.

      As file associations should be made only after the executable that handles them is installed, I select the Installation screen in the tree, then I click on the Insert button to add the desired action. In the displayed Select an Installation Action dialog box, I filter the shown list by entering the first letters of “association” to quickly find the Create a file association action among the 60+ preprogrammed actions.

      Once I click on OK, install4j appends the new action to the Installation screen, and in the properties list associated to the action, I enter “sh3dFile extension, describe it as “Sweet Home 3D document” and select the SweetHome3D launcher.

      Then I add the file associations for sh3f, sh3t, sh3p and sh3l extensions in the same way.

      For the action that should launch Sweet Home 3D at the end of the installation process, I select the Finish screen, click on the Insert button and select Add action. In the displayed Select an Installation Action dialog box, I filter the actions list with the first letters of “launcher” and select Execute launcher action.

      Once I click on OK, install4j asks me whether I want to add a check box to the Finish screen that will will let the user choose to launch the program or not.

      I accept and in the properties list of the Execute launcher action, I finally choose SweetHome3D as the launcher to run.

      At the end, I get the following list of screens and actions for Sweet Home 3D installer.

      Media

      As I don’t need Custom code or Update features at this time, I jump to the last part of the installer preparation by clicking on Media icon, then double-clicking on New media file icon.

      This will launch a wizard to configure a Media file. As I prefer an executable installer, I choose Windows in the Installer type combo box.

      In the Configure installer options step, I change installation directory to “Sweet Home 3D“.

      The Installer data files step doesn’t need any change since I want to create one installer file that will contain everything required.

      I don’t check the 64-bit executable option in the Select the architecture of the generated executables step since the Java 3D DLLs delivered with Sweet Home 3D are 32-bit only.

      As I don’t have any code certificate I must pass the Configure code signing for launchers and installer step too.

      The Bundle a JRE with your application step is more interesting for my use case.

      As I want to bundle a JRE with Sweet Home 3D to spare users the installation of a JRE, I select the Bundle the following JRE option and chose the most recent one after clicking on Download JREs.

      Once the JRE is downloaded, I select it in the Bundle the following JRE combo box.

      I’m not interested by any of the Customize project default settings last step, and I can finish the Media Wizard execution that will add an icon for the newly created media.

      Build

      The installer is now ready to be built. I click on Build icon and then on Start Build button.

      After 60 seconds, the installer is generated, and my first surprise is than the generated SweetHome3D-3.0-windows.exe file is more than 4 MB smaller than the one generated by Inno Setup (26 MB instead of 30.6 MB)! This is probably due to Pack200 compression algorithm.

      Test

      I double-click on the new installer icon to launch it and get the expected installation screens sequence.

       

       

       

       

       

       

       

       

      Once Sweet Home 3D is installed and launched, I check how it’s listed in the Processes tab of the Windows Task Manager: it appears as SweetHome3D.exe which is much nicer than javaw.exe.

      Conclusion

      With install4j you can easily create an installer and launcher for your Java application. Even if there are many steps in this installer wizard, you really feel install4j takes you by the hand to the right target. But in fact, install4j offers much more features that I’ll test in a second article.

      I’ll use install4j to download some optional files for Sweet Home 3D and configure some program parameters, like memory settings, system properties and default preferences files.

      I’ll also show how to use the different installation modes and how to update the program automatically.

      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.