JMOD(1)
π
bestie, meet jmod β straight from the JDK Commands manual (JMOD(1)) π
okay so real talk: this is the jmod page, and she is very specific but very iconic. We're talking create JMOD files, list what's inside existing ones, and generally do build-time main character things. Let's go π
β¨ NAME β¨
jmod β create JMOD files and list the content of existing JMOD files. that's the name, no cap π
πΈ SYNOPSIS πΈ
jmod (create|extract|list|describe|hash) [options] jmod-file
Includes the following:
π Main operation modes π
createβ Creates a new JMOD archive file. fresh archive, who dis? β¨extractβ Extracts all the files from the JMOD archive file. unzip vibes.listβ Prints the names of all the entries. the cast list, basically.describeβ Prints the module details. spill the tea.hashβ Determines leaf modules and records the hashes of the dependencies that directly and indirectly require them. cryptographic tying, but make it fashion.
π«Ά Options π«Ά
options β See Options for jmod.
π Required π
jmod-file β Specifies the name of the JMOD file to create or from which to retrieve information.
π¦ DESCRIPTION π¦
Note: For most development tasks, including deploying modules on the module path or publishing them to a Maven repository, continue to package modules in modular JAR files. Thejmodtool is intended for modules that have native libraries or other configuration files, or for modules that you intend to link, with thejlinktool, to a runtime image. π
The JMOD file format lets you aggregate files other than .class files, metadata, and resources. This format is transportable but not executable, which means you can use it during compile time or link time but not at run time. so no, you can't just yeet it and run it, bestie π
Many jmod options involve specifying a path whose contents are copied into the resulting JMOD files. These options copy all the contents of the specified path, including subdirectories and their contents, but exclude files whose names match the pattern specified by the --exclude option. ok so it's giving copy-paste but with a bouncer at the door πͺβ¨
With the --hash-modules option or the jmod hash command, you can, in each module's descriptor, record hashes of the content of the modules that are allowed to depend upon it, thus "tying" together these modules. This enables a package to be exported to one or more specifically-named modules and to no others through qualified exports. The runtime verifies if the recorded hash of a module matches the one resolved at run time; if not, the runtime returns an error. so if the hash doesn't match, it's a whole error moment π
π₯ OPTIONS FOR JMOD π₯
okay bestie, here comes the whole flag parade. every single one is getting her moment π
--class-pathpath β Specifies the location of application JAR files or a directory containing classes to copy into the resulting JMOD file.--cmdspath β Specifies the location of native commands to copy into the resulting JMOD file.--compresscompress β Specifies the compression to use in creating the JMOD file. The accepted values arezip-[0-9], wherezip-0provides no compression, andzip-9provides the best compression. Default iszip-6.--configpath β Specifies the location of user-editable configuration files to copy into the resulting JMOD file.--dateTIMESTAMPβ The timestamp in ISO-8601 extended offset date-time with optional time-zone format, to use for the timestamp of the entries, e.g."2022-02-12T12:30:00-05:00". This is exactly how the option is printed here, bestie β the create examples below use--date.--dirpath β Specifies the location wherejmodputs extracted files from the specified JMOD archive.--dry-runβ Performs a dry run of hash mode. It identifies leaf modules and their required modules without recording any hash values.--excludepattern-list β Excludes files matching the supplied comma-separated pattern list, each element using one of the following forms:glob-patternglob:glob-patternregex:regex-pattern
See the FileSystem.getPathMatcher method for the syntax of glob-pattern. See the Pattern class for the syntax of regex-pattern, which represents a regular expression.
--hash-modulesregex-pattern β Determines the leaf modules and records the hashes of the dependencies directly and indirectly requiring them, based on the module graph of the modules matching the givenregex-pattern. The hashes are recorded in the JMOD archive file being created, or a JMOD archive or modular JAR on the module path specified by thejmod hashcommand.--header-filespath β Specifies the location of header files to copy into the resulting JMOD file.--helpor-hβ Prints a usage message.--help-extraβ Prints help for extra options.--legal-noticespath β Specifies the location of legal notices to copy into the resulting JMOD file.--libspath β Specifies location of native libraries to copy into the resulting JMOD file.--main-classclass-name β Specifies main class to record in themodule-info.classfile.--man-pagespath β Specifies the location of man pages to copy into the resulting JMOD file.--module-versionmodule-version β Specifies the module version to record in themodule-info.classfile.--module-pathpath or-ppath β Specifies the module path. This option is required if you also specify--hash-modules.--target-platformplatform β Specifies the target platform of a JMOD file intended for a specific operating system and architecture. The value should follow the format<os>-<arch>, where<os>is the operating system and<arch>is the hardware architecture. Example values includelinux-amd64,windows-amd64, andmacos-aarch64.--versionβ Prints version information of thejmodtool.@filenameβ Reads options from the specified file.
An options file is a text file that contains the options and values that you would ordinarily enter in a command prompt. Options may appear on one line or on several lines. You may not specify environment variables for path names. You may comment out lines by prefixing a hash symbol (#) to the beginning of the line.
The following is an example of an options file for the jmod command:
#Wed Dec 07 00:40:19 EST 2016
create --class-path mods/com.greetings --module-path mlib
--cmds commands --config configfiles --header-files src/h
--libs lib --main-class com.greetings.Main
--man-pages man --module-version 1.0
--target-platform "macos-aarch64" greetingsmod
π EXTRA OPTIONS FOR JMOD π
In addition to the options described in Options for jmod, the following are extra options that can be used with the command. these are the bonus tracks πΏ
--do-not-resolve-by-defaultβ Exclude from the default root set of modules.--warn-if-resolvedβ Hint for a tool to issue a warning if the module is resolved. One ofdeprecated,deprecated-for-removal, orincubating.
π JMOD CREATE EXAMPLES π
π Create a JMOD file containing only compiled classes:
jmod create --class-path build/foo/classes jmods/foo1.jmod
π Create a JMOD file specifying the date for the entries as 2022 March 15 00:00:00:
jmod create --class-path build/foo/classes --date 2022-03-15T00:00:00Z
jmods/foo2.jmod
π Create a JMOD file bundling compiled classes, native commands, configuration files, header files, native libraries, man pages, and metadata including the main class, module version, and target platform details:
jmod create --class-path mods/com.greetings --cmds commands
--config configfiles --header-files src/h --libs lib
--man-pages man --main-class com.greetings.Main --module-version 1.0
--target-platform "macos-aarch64" greetingsmod
π¦ JMOD HASH EXAMPLE π¦
okay bestie, so this example is gonna show you exactly what happens when you try to link a leaf module (in this example, ma) with a required module (mb), and the hash value recorded in the required module doesn't match that of the leaf module. it's giving "vibe check failed" energy and honestly? iconic behavior from the tool. π
- Create and compile the following
.javafiles:jmodhashex/src/ma/module-info.java
module ma {
requires mb;
}
jmodhashex/src/mb/module-info.java
module mb {
}
jmodhashex2/src/ma/module-info.java
module ma {
requires mb;
}
jmodhashex2/src/mb/module-info.java
module mb {
}
- Create a JMOD archive for each module. create the directories
jmodhashex/jmodsandjmodhashex2/jmods, and then run the following commands from thejmodhashexdirectory, then from thejmodhashex2directory:jmod create --class-path mods/ma jmods/ma.jmodjmod create --class-path mods/mb jmods/mb.jmod
- Optionally preview the
jmod hashcommand. run the following command from thejmodhashexdirectory:
jmod hash --dry-run -module-path jmods --hash-modules .*
The command prints the following:
Dry run:
mb
hashes ma SHA-256 07667d5032004b37b42ec2bb81b46df380cf29e66962a16481ace2e71e74073a
This indicates that the jmod hash command (without the --dry-run option) will record the hash value of the leaf module ma in the module mb. β¨ it's a sneak peek, a little trailer, a dry run bestie, nothing gets written yet π
- Record hash values in the JMOD archive files contained in the
jmodhashexdirectory. run the following command from thejmodhashexdirectory:
jmod hash --module-path jmods --hash-modules .*
The command prints the following:
Hashes are recorded in module mb
slay, the hash is officially in its new home π‘
- Print information about each JMOD archive contained in the
jmodhashexdirectory. run the highlighted commands from thejmodhashexdirectory:
jmod describe jmods/ma.jmod
ma
requires mandated java.base
requires mb
jmod describe jmods/mb.jmod
mb
requires mandated java.base
hashes ma SHA-256 07667d5032004b37b42ec2bb81b46df380cf29e66962a16481ace2e71e74073a
look at that hash sitting in mb like it owns the place π
- Attempt to create a runtime image that contains the module
mafrom the directoryjmodhashex2but the modulembfrom the directoryjmodhashex. run the following command from thejmodhashex2directory:- Linux and macOS:
jlink --module-path $JAVA_HOME/jmods:jmods/ma.jmod:../jmodβ
hashex/jmods/mb.jmod --add-modules ma --output ma-app
- Windows:
jlink --module-path %JAβ
VA_HOME%/jmods;jmods/ma.jmod;../jmodβ
hashex/jmods/mb.jmod --add-modules ma --output ma-app
The command prints an error message similar to the following:
Error: Hash of ma (a2d77889b0cb067df02a3abc39b01ac1151966157a68dc4241562c60499150d2) differs to
expected hash (07667d5032004b37b42ec2bb81b46df380cf29e66962a16481ace2e71e74073a) recorded in mb
and there it is β the moment the vibes do NOT match. π the hash ofmaand the hash recorded inmbare literally different, sojlinksays nope. no runtime image for you today, bestie. this is exactly what the hash check is for. π
and that's the whole example, start to finish β you built the archives, previewed the hash, recorded it, described it, and then watched the mismatch get caught in 4K. character development fr fr π§
sign-off time π this little masterpiece comes from JDK 27-ea, dated 2026, and it lives in section JMOD(1) of your friendly neighborhood manual pages. go forth and hash responsibly, bestie π«Άπ
π¦ where this page comes from
- epel 10: java-latest-openjdk-devel 1:27.0.0.0.35-0.0.1.0.ea.el10_3 Β· Apache-1.1 AND Apache-2.0 AND LicenseRef-Callaway-BSD AND LicenseRef-Callaway-BSD-with-advertising AND GPL-1.0-or-later AND GPL-2.0-only AND LicenseRef-Callaway-GPLv2-with-exceptions AND IJG AND LicenseRef-Callaway-LGPLv2+ AND LicenseRef-Callaway-MIT AND MPL-2.0 AND LicenseRef-Callaway-Public-Domain AND W3C AND Zlib AND ISC AND FTL AND LicenseRef-RSA
- epel 10: java-latest-openjdk-devel-fastdebug 1:27.0.0.0.35-0.0.1.0.ea.el10_3 Β· Apache-1.1 AND Apache-2.0 AND LicenseRef-Callaway-BSD AND LicenseRef-Callaway-BSD-with-advertising AND GPL-1.0-or-later AND GPL-2.0-only AND LicenseRef-Callaway-GPLv2-with-exceptions AND IJG AND LicenseRef-Callaway-LGPLv2+ AND LicenseRef-Callaway-MIT AND MPL-2.0 AND LicenseRef-Callaway-Public-Domain AND W3C AND Zlib AND ISC AND FTL AND LicenseRef-RSA
- epel 10: java-latest-openjdk-devel-slowdebug 1:27.0.0.0.35-0.0.1.0.ea.el10_3 Β· Apache-1.1 AND Apache-2.0 AND LicenseRef-Callaway-BSD AND LicenseRef-Callaway-BSD-with-advertising AND GPL-1.0-or-later AND GPL-2.0-only AND LicenseRef-Callaway-GPLv2-with-exceptions AND IJG AND LicenseRef-Callaway-LGPLv2+ AND LicenseRef-Callaway-MIT AND MPL-2.0 AND LicenseRef-Callaway-Public-Domain AND W3C AND Zlib AND ISC AND FTL AND LicenseRef-RSA
- epel 9: java-latest-openjdk-devel 1:27.0.0.0.35-0.0.1.0.ea.el9 Β· Apache-1.1 AND Apache-2.0 AND LicenseRef-Callaway-BSD AND LicenseRef-Callaway-BSD-with-advertising AND GPL-1.0-or-later AND GPL-2.0-only AND LicenseRef-Callaway-GPLv2-with-exceptions AND IJG AND LicenseRef-Callaway-LGPLv2+ AND LicenseRef-Callaway-MIT AND MPL-2.0 AND LicenseRef-Callaway-Public-Domain AND W3C AND Zlib AND ISC AND FTL AND LicenseRef-RSA
- epel 9: java-latest-openjdk-devel-fastdebug 1:27.0.0.0.35-0.0.1.0.ea.el9 Β· Apache-1.1 AND Apache-2.0 AND LicenseRef-Callaway-BSD AND LicenseRef-Callaway-BSD-with-advertising AND GPL-1.0-or-later AND GPL-2.0-only AND LicenseRef-Callaway-GPLv2-with-exceptions AND IJG AND LicenseRef-Callaway-LGPLv2+ AND LicenseRef-Callaway-MIT AND MPL-2.0 AND LicenseRef-Callaway-Public-Domain AND W3C AND Zlib AND ISC AND FTL AND LicenseRef-RSA
- epel 9: java-latest-openjdk-devel-slowdebug 1:27.0.0.0.35-0.0.1.0.ea.el9 Β· Apache-1.1 AND Apache-2.0 AND LicenseRef-Callaway-BSD AND LicenseRef-Callaway-BSD-with-advertising AND GPL-1.0-or-later AND GPL-2.0-only AND LicenseRef-Callaway-GPLv2-with-exceptions AND IJG AND LicenseRef-Callaway-LGPLv2+ AND LicenseRef-Callaway-MIT AND MPL-2.0 AND LicenseRef-Callaway-Public-Domain AND W3C AND Zlib AND ISC AND FTL AND LicenseRef-RSA
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms