What's new in install4j 11.0

Change release:

Please see the change log for a detailed list of changes. Screenshots are also available in dark mode.

For a discussion of breaking changes when migrating from install4j 10, please see this blog post.

install4j 11.0 introduces the following notable new features:

macOS notarization is now cross-platform. Previously, notarization required macOS, either for building or for manual post-processing. From install4j 11 onwards, install4j can perform the notarization process on any platform. This allows install4j builds to be fully cross-platform.

The App Store Connect API required for notarization operations is now configured with the issuer ID, the key ID and the private API key that are obtained from App Store Connect.

Screenshot

PKCS #11 code signing improvements. The PKCS #11 implementation has been rewritten from scratch without the use of the SunPKCS11 Java Security Provider. This enables the implementation of more features for PKCS #11 and provides better error messages in case of configuration problems.

In this release, we added a selection dialog for the PKCS #11 slot index that lists HSM descriptions and manufacturers. This is important if you have multiple HSMs.

Screenshot

In install4j 11, you can now select a certificate by its label, as well as by its issuer and serial number Also, if you leave the certificate selection empty, install4j will automatically select the code signing certificate with the longest validity period.

Screenshot

Up to install4j 11, PKCS #11 was only available for Windows code signing. Now there is a PKCS #11 option for macOS code signing as well.

Screenshot

Windows code signing has been improved. Instead of configuring a code signing executable in the "Executable processing" step in the media wizard for all Windows media files, you can now configure an executable like Azure Sign Tool on the "General Settings → Code Signing" step. The command is called for each executable that has to be signed including the generated launchers.

Screenshot

With the chained certificates directory, it is now possible to tell install4j about intermediate certificates that need to be taken into account for code signing to establish the complete hierarchy of trust.

Screenshot

Major improvements in the script editor. When developing an installer with install4j, you usually make extensive use of the script editor. Although the script editor previously included code completion and problem detection, it lacked many features that you would expect from a modern IDE. In install4j 11, we implemented a lot of functionality to boost your productivity with install4j.

Caret highlights have been implemented in the script editor. Read and write access have different background colors, and the right gutter shows occurrences that can be navigated to by clicking on them.
Screenshot

Code completion has been improved. It now suggests automatically as you type by default. You can disable this behavior in the Java editor settings dialog.

There are now a number of templates that are tab-expandable for common code snippets, such as printing to stderr with "serr", as shown in the screenshot below. Other snippets, for example, are "log" to write to the log file and "ex" to log an exception.

Also, all static methods in install4j API classes are suggested without having to first type the class name. In that way, you can start with a method name and install4j will add the static import for the class automatically.

Screenshot

An action to rename variables has been added (Code → Rename).

Screenshot

A new action allows you to reformat the entire script or selected code (Code → Reformat Code). Reformatting is done according to the Eclipse default Java formatting style. If you would like to use custom formatting settings, you can export a single Eclipse profile and specify it in the Java editor settings. Exporting Eclipse XML profile files is supported by Eclipse, IntelliJ IDEA and the RedHat Java plugin of VS Code. The tab size used for editing and reformatting is directly configurable in the Java editor settings.

Also, typing a closing brace now reformats the preceding block. This behavior can be disabled in the Java editor settings.

Screenshot

An action to optimize the imports for the current script has been added (Code → Optimize Imports).

Screenshot

An action to show the available parameters for all overloaded methods of the method call at the caret has been added (Code → Parameter Info). It highlights the matched arguments up to caret and selects the overloaded variant chosen during code completion if possible.

Screenshot

Actions to navigate between problems have been added to the script editor. Problems are either warnings or errors and can be shown by hovering over the underlined text or the indicator in the right gutter.

Screenshot

Selecting code blocks is now possible with the new "Extend selection" and "Shrink selection" actions. Repeated invocations of those actions select surrounding or contained blocks of code around the current caret position.

Screenshot

The script editor now has support for quick fixes. If the caret is on a detected problem, a floating popup with a lightbulb or the Code → Quick Fix action will show a context menu with automatic modifications that will resolve the problem. The list of available quick fixes include:

  • Remove unused, duplicate, conflicting or non-existent imports
  • Import ambiguous or unresolved types
  • Fix unterminated strings
  • Fix type mismatches
  • Fix wrong return statements
  • Fix instance access to static members
  • Fix wrong visibilities and method modifiers in overrides
  • Fix abstract modifier problems
  • Implement unimplemented methods
  • Create local unresolved variable
  • Remove unused local variables
  • Remove dead code
  • Remove casts
Screenshot

An new action has been introduced to refactor code (Code → Refactor). When invoked, a popup with applicable refactorings for the current caret position is shown. The list of available refactorings include:

  • Extract to local variable
  • Inline local variable
  • Convert to lambda expression
  • Convert to anonymous class creation
  • Convert var to an explicit type and vice versa
  • Convert to static import
  • Surround with try/catch
  • Convert to enhanced for loop
  • Add inferred lambda parameter type
  • Replace lambda parameter types with var
  • Change lambda body expression to block
  • Change body block to expression
  • Remove lambda parameter types
  • Convert lambda to method reference
  • Use MessageFormat for string concatenation
  • Use StringBuilder for string concatenation
  • Use "String.format" for string concatenation
  • Convert String concatenation to text block
  • Convert to switch expression
  • Split variable declaration
  • Join variable declaration
  • Invert equals comparison
Screenshot

Alternative keymaps for popular IDEs are now supported by the script editor. When first using the script editor, install4j will ask you to choose an initial keymap.

Screenshot

You can change the keymap or customize it at any later time by invoking Settings → Keymap in the Java editor settings.

Screenshot

install4j 11 delivers several important improvements for compiler variables. Compiler variables are used to define values that are used in multiple places in the project and to customize the project externally from your build system.

Compiler variables can be now declared to contain sensitive information. In that case, their value is not written to the runtime configuration and cannot be retrieved via context.getCompilerVariable("variableName"). You can still use the compiler variable in all text fields with the ${compiler:variableName} syntax because these usages are replaced at build time.

Screenshot

Platform-specific overrides for compiler variables were added. While it was always possible to override compiler variable values for media files, it was inconvenient when the overriding value was always identical for the same platform. Now, you can override for Windows, macOS and Linux/Unix. These overrides can be further refined with the media-specific overrides.

Screenshot

You can now refer to the base value when overriding a compiler variable with the syntax ${compiler:variableName}. This applies to both platform-specific and media-specific overrides. There are many related use cases, for example, a list of VM parameters with common values and additional values for each platform. Previously, you would have had to introduce a separate compiler variable for the additional value.

Screenshot

File and path separators can be converted to the build or the target platform. This means you do not have to repeatedly use the compiler variables sys.fileSeparator, sys.pathlistSeparator, sys.mediaFileSeparator or sys.mediaPathlistSeparator anymore. Instead, you can use either Unix-style ('/' and ':') or Windows-style ('\' and ';') file and path separators in the value. Both styles are converted in the same way.

Screenshot

This feature has also been implemented for pre-defined installer variables of type String.

Screenshot

Actions to read and modify JSON files were added. The mechanism to select parts of a JSON document that should be read or modified is the JSONPath expression. JSON actions use the Jayway JsonPath library. A shadowed copy of this library is only bundled with the installer if at least one JSON action is used in your project.

The "Read value from a JSON file" action saves the match of the JSONPath to the specified variable. Depending on the JSONPath expression, the variable is either a primitive value, an instance of java.util.List for array matches, or an instance of java.util.Map for object matches.

Screenshot

The "Count occurrences in a JSON file" action counts the number of matches of the JSONPath and saves the result to the specified variable. In this case, the JSONPath expression should be an indefinite expression.

Screenshot

Finally, the "Modify JSON files" action replaces the matches of a JSONPath expression in one or multiple files. You can choose to

  • Set values
  • Replace values
  • Add to arrays
  • Delete values
  • Add or update object keys
  • Rename object keys

by adjusting the "Modification type" property and filling out its child properties.

Screenshot

Support for symlinks has been improved. The "Copy files and directories" and "Move files and directories" actions now fully support symlinks. Their "Symlink handling" property controls whether the content is copied or whether the same relative or absolute target should be used. The "On symlink creation failure" property offers different failure strategies during symlink handling.

Screenshot

The "Create a symbolic link" action now also supports Windows. Execution on Windows is controlled by the "Execute on Windows" property and is disabled by default.

Screenshot

The support for reusing the installed JRE in update installers was improved. There is now a "Previous installations" search sequence entry type under "General Settings → JRE Bundles → Search Sequence" that allows you to reuse the installed JRE in update installers. Only installations with the same application ID are considered.

If a JRE was found in that way, the "Install files" action now copies that JRE from a different installation to the current installation directory. This prevents problems that would otherwise occur when the previous installation is uninstalled.

Screenshot

Update downloaders can now make decisions based on the Java version of the update installer by inspecting com.install4j.api.update.UpdateDescriptorEntry#getJreMinVersion and #getJreMaxVersion. In that way, you can choose to download an update installer without a bundled JRE if you can determine that the requirements for the JRE have not changed. Other attributes in the update descriptor can also be used for this purpose. These attributes are configurable under "Installer → Auto Update Options".

The initial progress dialog of Windows installers now supports dark mode. In those cases where the installer will be shown in dark mode, the initial progress dialog will also have a dark theme. This is a native dialog and so its styling slightly differs from the main installer window.

This feature works for Windows 11 and higher.

Screenshot

Installers are now localized into Ukrainian.

Localizations are configured under "General Settings → Languages".

Screenshot

The options presented to the user in case of action failures are now more flexible.

The "Ask user" failure strategy for actions and action groups now has separate sub-options for allowing "Retry", "Ignore" and "Quit" answers from the user. Previously there were only limited fixed combinations.

Screenshot

The selection script of several form components is now more flexible.

The "Checkbox", "Single radio button" and "Radio button group" form components received an "Also execute when screen is activated" property as a child property of the "Selection script" property for cases where the script manages the visibility or enablement of other form components.

Screenshot

Multi-line labels can be made selectable.

The "Multi-line label" and the "Multi-line HTML label" form components have received a "Make text selectable" property so that the user can select text with the mouse and copy it to the clipboard.

Screenshot

Gradle, Maven, and Ant plugins can now auto-provision the appropriate version of install4j.

Specifying the "installDir" parameter is still possible, but no longer required.

Here's an example of a minimal Gradle script that builds an installer with install4j 11.0:

import com.install4j.gradle.Install4jTask

plugins {
    id("com.install4j.gradle") version "11.0"
}

tasks.register<Install4jTask>("media") {
  projectFile = file("hello.install4j")
}

A Maven POM to compile an installer will look like this:

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.test.hello</groupId>
  <artifactId>hello-world</artifactId>
  <version>1.0</version>

  <pluginRepositories>
    <pluginRepository>
      <id>ej-technologies</id>
      <url>https://maven.ej-technologies.com/repository</url>
    </pluginRepository>
  </pluginRepositories>

  <build>
    <plugins>
      <plugin>
        <groupId>com.install4j</groupId>
        <artifactId>install4j-maven</artifactId>
        <version>11.0</version>
        <executions>
          <execution>
            <goals>
              <goal>compile</goal>
            </goals>
            <configuration>
              <projectFile>${project.basedir}/hello.install4j</projectFile>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

The earlier method of specifying the "installDir" property remains available.

The Gradle plugin now works with the configuration cache.

To check whether media files are up to date, the Gradle task would need to determine the list of input files. Because the plugin cannot do that without invoking the compiler, the install4j task is never up to date and is always executed. Starting with 11.0, if you define your own file inputs on the task, the up-to-date check is enabled.

You can track input files with calls like

...
inputs.dir(stagingDir)
inputs.files(file1, file2)
...

in the task definition.

To support the configuration cache, we had to migrate all properties to Gradle providers. This means that the binary interface of the tasks has changed and you will likely have to adjust your build script.