Overview

The Java Platform Module System (JPMS) was introduced in Java 9. It allows you to organize your code by grouping a set of related packages into higher-level components called modules, and provides a mechanism to declare dependencies between modules.


Modularizing your application offers several benefits:

 - An application whose code is organized into modules is easier to read, easier to maintain, and more scalable.

 - Dependencies between modules are defined via module descriptors that are both checked at compile time and when the application is launched. This early resolution of dependencies helps improve runtime reliability, overcoming a long-standing issue in Java where "NoClassDefFoundError" exceptions were common causes of application crashes.

 - The packages in a module are accessible to other modules only if they are explicitly exported. This principle, called strong encapsulation, provides by default a secure space for the code into which reflection cannot intrude.

 - Finally, the module system allows you to create custom runtime images containing only the modules used by your application. The reduced sized of the runtime environment noticeably improves the startup time and memory footprint of the application.


Starting from version 3.5.55, the wrapper.jar file contains a module descriptor which introduces the 'org.tanukisoftware.wrapper' module. This named module can be included in custom runtime images created with jlink.

WARNING

Before version 3.5.55, the wrapper.jar file was not modular. When referenced in the module path, an automatic module named 'wrapper' (derived from the name of the JAR file) was created. This automatic module could be used in other module declarations, but could not be used by jlink to create runtime images.

If 'wrapper' was used in some of your module descriptors, and you upgrade to Wrapper version 3.5.55 or above, don't forget to change the name to 'org.tanukisoftware.wrapper'.


The Wrapper provides several properties to help you configure how modules are used by your application:

NOTE

These properties are only used when running with versions of Java 9 or above. They will be ignored on earlier versions.

wrapper.java.module_path.<n>

Compatibility :3.5.55, Requires Java 9+
Editions :Professional EditionStandard EditionCommunity Edition
Platforms :WindowsMac OSXLinuxIBM AIXFreeBSDHP-UXSolarisIBM z/Linux

These properties are used to list locations where modules of your application can be found. The list can contain directories, or paths to jar files optionally containing wildcards in the filename portion.

The Wrapper will use this list to build the '--module-path' option of the Java command line.

If a wildcard character is used within a modulepath entry, all matching files will be added to the modulepath used when launching a JVM instance.

Valid wildcard characters are:

  • A '*' character, which will match "0" (zero) or more characters.
  • A '?' character, which will match exactly one character.

Examples of possible values for modulepath elements:
wrapper.java.module_path.1=../lib/myapp-*.jar  # jar files specified with a wildcard
wrapper.java.module_path.2=../lib/tools.jar    # single jar file specified using the exact name
wrapper.java.module_path.3=../lib/ext          # folder where additional modules can be found

NOTE

wrapper.jar should not be included in the values of this property list. If it is present, it will be removed from the list when loading the configuration.

The Wrapper uses the wrapper.jarfile property to automatically add the wrapper.jar file at the correct place in the command line depending on whether modules are used or not.


Classpath:

Java does not allow two distinct jar files containing the same package to co-exist in the modulepath list. This is not the case with classpath, where historically package overlapping has always been allowed. This is one of the reasons why classpath remains useful, at least until an application can be fully migrated to the Java 9 module system.

Please be aware of the following limitation: jar files listed in the classpath that cannot be found in any locations of the modulepath will be used by the JVM as an unnamed module, which by nature makes it inaccessible to any other modules. If a module is supposed to be referenced in a requires directive of another module, it must exist in one of the locations specified by the wrapper.java.module_path.<n> or wrapper.java.upgrade_module_path.<n> properties.


Problems?

If you encounter any problems related to modulepath, the first thing that should be done is to verify the full modulepath being generated by the Wrapper. To do this, either enable debug log output with the wrapper.debug property, or enable the display of the Java command using the wrapper.java.command.loglevel property.

NOTE

Modulepath containing spaces:

The Wrapper will correctly handle module path elements that contain spaces. This is done later by the Wrapper by enclosing the final generated module path in quotes. Individual module path element property values should never be defined containing quotes, even if they contain spaces.

wrapper.java.module_path.missing.loglevel

Compatibility :3.5.55, Requires Java 9+
Editions :Professional EditionStandard EditionCommunity Edition
Platforms :WindowsMac OSXLinuxIBM AIXFreeBSDHP-UXSolarisIBM z/Linux

By default, the Wrapper will log warnings about any missing Module Path elements at the DEBUG log level. It is fairly common to want to see these generated log messages without also enabling all of the debug output. This property makes it possible to specify the log level at which the warnings will be logged.

Valid property values include:
  • FATAL :
    to log at the FATAL log level.
  • ERROR :
    to log at the ERROR log level.
  • WARN :
    to log at the WARN log level.
  • STATUS :
    to log at the STATUS log level.
  • INFO :
    to log at the INFO log level.
  • DEBUG :
    to log at the DEBUG log level.
  • NONE :
    to never log.

The default value is DEBUG.

Example:
wrapper.java.module_path.missing.loglevel=DEBUG

If your application often has missing jars, then setting this value to NONE will disable warnings at any log level.

Module Path elements which are defined as wildcards will also log a warning if the wildcard fails to match at least one file. This can happen if the directory is missing or empty.

wrapper.java.upgrade_module_path.<n>

Compatibility :3.5.55, Requires Java 9+
Editions :Professional EditionStandard EditionCommunity Edition
Platforms :WindowsMac OSXLinuxIBM AIXFreeBSDHP-UXSolarisIBM z/Linux

These properties define a list which is similar to wrapper.java.module_path.<n>, but allow overriding upgradeable modules contained in the runtime image.

Just like for wrapper.java.module_path.<n>, the list can contain directories, or paths to jar files optionally containing wildcards in the filename portion. For more details on the syntax, please refer to the above section.

The Wrapper will use this list to build the '--upgrade-module-path' option of the Java command line.

NOTE

wrapper.jar doesn't need to be included in the values of this property list.

The Wrapper uses the wrapper.jarfile property to automatically add the wrapper.jar file at the correct place in the command line depending on whether modules are used or not.

wrapper.java.upgrade_module_path.missing.loglevel

Compatibility :3.5.55, Requires Java 9+
Editions :Professional EditionStandard EditionCommunity Edition
Platforms :WindowsMac OSXLinuxIBM AIXFreeBSDHP-UXSolarisIBM z/Linux

By default, the Wrapper will log warnings about any missing Upgrade Module Path elements at the DEBUG log level. It is fairly common to want to see these generated log messages without also enabling all of the debug output. This property makes it possible to specify the log level at which the warnings will be logged.

Valid property values include:
  • FATAL :
    to log at the FATAL log level.
  • ERROR :
    to log at the ERROR log level.
  • WARN :
    to log at the WARN log level.
  • STATUS :
    to log at the STATUS log level.
  • INFO :
    to log at the INFO log level.
  • DEBUG :
    to log at the DEBUG log level.
  • NONE :
    to never log.

The default value is DEBUG.

Example:
wrapper.java.upgrade_module_path.missing.loglevel=DEBUG

If your application often has missing jars, then setting this value to NONE will disable warnings at any log level.

Upgrade Module Path elements which are defined as wildcards will also log a warning if the wildcard fails to match at least one file. This can happen if the directory is missing or empty.

wrapper.java.module.<n>

Compatibility :3.5.55, Requires Java 9+
Editions :Professional EditionStandard EditionCommunity Edition
Platforms :WindowsMac OSXLinuxIBM AIXFreeBSDHP-UXSolarisIBM z/Linux

These properties are used to list the names of the root modules used by your application. Root modules are modules that cannot be pulled in the module graph when the application is launched, either because they are not required by any other modules, or because they are optional dependencies (i.e. specified with 'requires static' in a module descriptor).

The Wrapper will use this list to build the '--add-modules' option of the Java command line.

In addition to module names, the list can include the following tokens:

Please see the OpenJDK specification for a more detailed description.