New web license service and improvements for the on-premises server

Customers with floating licenses now have more flexibility: Starting with with the most recent releases of JProfiler and install4j, we now offer a web license service, so you do not have to install a license server yourself. If you choose that option, you will receive a license key that can be distributed to all developers and is entered just like a single license key. This option requires the ability to make an outgoing HTTP request to our license server.

Going forward, we will be offering both the web as well as the the on-premises solution. For the time being, the on-premises option remains the default and you can contact us if you would like to switch to the web option.

There is also good news for the on-premises license server with two great improvements that are available in the latest release:

Remote checkout

When you take your computer offsite where you don’t have access to the license server, you can check out a license for a number of days in the license dialog (Help->Enter License Key):

The maximum allowed number of days is configurable in the license server configuration and is set to 1 by default. If you return early, you can give the license back to the license server so it becomes available for other team members:

Encryption and Authentication

Previously, you could either choose an unencrypted direct connection suitable for local networks or an SSH connection suitable for use over the internet. However, the latter required SSH server access to the license server machine.

With the latest releases, you can enable encryption in the license server configuration and connect directly over the internet with mutual authentication and TLS encryption. The license server creates a file encryption/client.ks at startup (if it does not exist) that must be distributed to users and entered in the license dialog:

Without that file, no connection to the license server is possible. To reset the authentication, simply delete the “encryption” folder in the license server installation and restart the license server. A new authentication file will then be generated.

Migrating to install4j 9

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

  • The minimum Java version for the install4j runtime is now Java 1.8. Java 1.7 is no longer supported.
  • The install4j compiler and IDE now require at least Java 11. This is only relevant on Linux and Unix where no JRE is bundled.
  • “Install files” action: The “Update bundled” JRE property has been removed. A bundled JREs is now always updated if the update installer also includes a bundled JRE. The ability to switch this off offers no benefit and has the potential to create severe problems during sequential upgrades. If you had this property selected, you can restore the previous behavior by defining the VM parameter -Dinstall4j.preventJreBundleUpdate=true in the installer.
  • “HTTP request” action: In previous versions, if an error occurred, the response code variable and the response header variables were not set. This error has been corrected in install4j 9, but it changes the semantics of the installer variables.
  • The installer variable sys.appdataDir was previously undefined on Unix, it now returns the value of the environment variable XDG_DATA_HOME ( ~/.local/share ) on Unix.
  • Shared JREs (Windows and Unix) now have a sharing ID. This has become necessary because there is no universal definition of a JRE anymore so the scope of sharing has to be restricted. Consequently, shared JREs are now installed in different locations than before. Also, the user-specific root directories have changed to ~/.local/share/i4j_jres on Unix and %APPDATA%\Local\Programs\Common\i4j_jres on Windows. Shared JREs are now preferred to public JREs on Unix.
  • The “Execute launcher” action always executed the selected launcher without elevation. This does not work for launchers that require privileges themselves. Since install4j 9, the action respects the “Action elevation type” property of the action. This changes the behavior of the action if you have changed the “Action elevation type” property from its default value of “Do not elevate” to another property value.
  • The auto-update integration for background update downloaders in the launcher wizard behaves differently if the “Unattended mode with progress dialog” mode is selected: It now shows errors and alerts in the update installer where previously any error would lead to a silent failure. If this change is not acceptable for you, you can add the VM parameter -Dinstall4j.noAlerts=true to the “VM parameters” property of the installer.
  • Installer applications that have not been started in-process by launchers now set the system property jdk.lang.Process.allowAmbiguousCommands=false to avoid cmd.exe injections. In unattended and console mode, installers applications already behaved that way because they use a security manager. Some quoting strategies or arguments that worked before might stop working in GUI mode because of that change. To revert to the previous behavior, set the VM parameter -D jdk.lang.Process.allowAmbiguousCommands=true for the installer application.
  • The JRE version cache on Linux/Unix is now located in .cache/install4j/jres instead of the file ~/.install4j .
  • Config files, cached files and pre-crated JRE bundles have new platform-specific locations instead of being stored in ~/.install4j<version> . On Windows, all directories are located below %LOCALAPPDATA%/install4j/v<version> . On macOS, ~/Library/Application Support/install4j/v<version> is used for config files as well as pre-created JRE bundles and ~/Library/Caches/install4j/v<version> is used for cached files. On Linux and Unix, .config/install4j/v<version> is used for config files, .caches/install4j/v<version> for caches and .local/share/install4j/v<version> for pre-created JRE bundles. The environment variables XDG_CONFIG_HOME , XDG_CACHE_HOME and XDG_DATA_HOME modify the roots of these directories, respectively.
  • In previous versions, Linux/Unix installers created the installation directory with the default umask. Since install4j 9, the default Unix directory mode configured in the “Files->File Options” view or the overridden mode configured for the “Installation directory” node in the distribution tree is used.

Support for macOS Apple Silicon

Please note: Several JDK providers now offer the macos-aarch64 architecture and there is no need anymore to create the bundle yourself, install4j can do this for you automatically.

(Edited on 2021-01-07 to include changes for install4j 8.0.10)

Apple machines with the new ARM architecture are now available. While you can run existing x64 binaries for on ARM machines through Rosetta, the performance may be impacted significantly. install4j 8.0.9 addresses this concern with support for native ARM binaries.

At the time of writing, the JRE port to macOS ARM has not landed in OpenJDK yet. Currently, only the JetBrains JDK provider includes a release with the macos-aarch64 architecture (

In addition, Azul provides distributions for macos ARM for several JDK versions. These JDKs can be processed with the “Project->Create a JRE bundle” command in the install4j IDE or the createbundle command line tool. This creates a “pre-created” JRE bundle that can be selected on the “Bundled JRE” step of the media wizard. An Azul JDK provider that would download these JDKs automatically and in a cross-platform way is planned for install4j 9.

After you have prepared a JRE bundle for macOS ARM, you can select the architecture in the macOS media wizard. You will still need an additional media file for Intel-based Macs, because ARM binaries do not run there.

Finally, select the pre-created bundle in the “Bundled JRE” step.

Migrating to install4j 8

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

  • The unattended installer does not ignore file installation failures anymore but fails at the first file installation failure. To get the old behavior, start the installer with the -nofilefailures argument. To permanently set this mode, add -Dinstall4j.noFileFailures=true to the “VM parameters” property of the installer.
  • When using the VM parameters -Dinstall4j.alternativeLogFile=<path> and its new alias -Dinstallj4.log=<path>
    now imply -Dinstall4j.keepLog=true , meaning that the log file is no longer deleted in case of a successful execution of the installer application.
  • The default file name of the error log for Windows installers has changed from error.log to ${compiler:sys.mediaFileName}_error.log . You can restore the old file name with the new “Log file for stderr” property of the installer.
  • In bean properties with an array type, installer variables with collection values are expanded as separate array elements. Previously this was only implemented if the installer variables had array values. In the API, this new behavior affects the AbstractBean.replaceVariables(...) methods with array parameters. If you rely on the toString() replacement of collections, you have to change the types of the related installer variables.
  • Variable names for all built-in variable systems can no longer contain the character sequence ?: which is now used for specifying default values for missing variables.
  • FormEnvironment.getId(...) now returns the display ID of the form component rather than the automatic ID. If you were checking for an explicit automatic ID and also defined a custom ID for a form component, that code will now fail.
  • The “Read text from file” action will now fail if an error occurred. Previously it always succeeded.
  • The compiler variable sys.platform now contains the value windows-x32 for 32-bit Windows media files instead of windows . For 64-bit Windows media files it remains windows-x64 .
  • The “Customize project defaults->Installer custom script” step of the Unix/Linux GUI installer media wizard has been removed. The custom script is now configured on the installer in the “Installer->Screens & Actions” step. The simple case where there is only one Unix/Linux GUI installer is migrated correctly. However, if you used different customizations for different Unix/Linux GUI installers, the migration will be incomplete and you have to solve it with compiler variables.
  • For Linux/Unix installers, the umask is now set to 0022 to allow execution by all users. This can be changed by setting the compiler variable sys.ext.installerUmask to another mask value or to false to prevent executing any umask command in the installer script.

Automation sandboxing in macOS 10.14

macOS 10.14 introduces automation sandboxing as part of a new push for security. This change impacts installers generated with install4j prior to 7.0.8, because they use AppleScript to perform a variety of tasks. The authorization dialogs from the new sandboxing mechanims are undesirable for an installer and once a permission is denied it is difficult to reauthorize it.

To solve this problem, nearly all affected operations have been re-implemented as native code in install4j 7.0.8. As part of this work we have fixed a long-standing issue on macOS: When requesting elevated privileges, the password dialog notified the user that “install4j” wants to make changes.

However, users most likely do not know the name “install4j” and could be tempted to cancel the dialog. Starting with install4j 7.0.8, the full name that is configured in your project is displayed instead:


Development Sneak Peek: Dark Mode and HiDPI

A system-wide dark mode is coming to both macOS and Windows. That’s why we’re working on a dark mode for JProfiler as well. Based on the excellent Darcula Look and Feel from our friends at JetBrains, JProfiler will soon fit into this new world of dark background colors:



Moreover, support for fractional HiDPI is coming for Windows. If you are using a 4K monitor, you will be happy to hear that the blurry upscaled UI will be a thing of the past. This is not only true for dark mode: We will also be using the light look and feel from IntelliJ IDEA together with the JetBrains Runtime in order to provide the best experience for high screen resolutions. The light mode will be the new default look and feel for JProfiler.



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 in the macOS EAWT API anymore, you have to use the new API methods, for example

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

    for the quit handler.

If you notice anything else, please let us know!

JProfiler’s integration into IntelliJ IDEA

This screencast shows the JProfiler plugin for IntelliJ IDEA. A run configuration is profiled, source code navigation is discussed and the call graph data display in the IDE is shown.

Finding a memory leak with JProfiler

This screencast explains a basic strategy for solving memory leaks with JProfiler.

There is an older version of this screencast from 2009 that is not accurate for the heap walker anymore but that shows other useful features in JProfiler.