The jpackage tool packages a Java application into a platform-specific package that includes all necessary dependencies. It is part of the jdk.jpackage module.
Basic Usage
jpackage --input input-dir --name AppName --main-jar app.jar --main-class com.example.Main
Source Code
The jpackage implementation is located at:
- Main class:
src/jdk.jpackage/share/classes/jdk/jpackage/main/Main.java:1
- CLI handler:
src/jdk.jpackage/share/classes/jdk/jpackage/internal/cli/Main.java:1
- Options:
src/jdk.jpackage/share/classes/jdk/jpackage/internal/cli/StandardOption.java:1
- Linux packager:
src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxPackager.java:1
Package Types
jpackage can create different types of packages depending on the platform:
Available formats:
deb - Debian package (.deb)
rpm - RPM package (.rpm)
app-image - Application image directory
jpackage --type deb --input lib --main-jar myapp.jar --name MyApp
jpackage --type rpm --input lib --main-jar myapp.jar --name MyApp
Available formats:
exe - Windows executable installer
msi - Windows MSI installer
app-image - Application image directory
jpackage --type exe --input lib --main-jar myapp.jar --name MyApp
jpackage --type msi --input lib --main-jar myapp.jar --name MyApp
Available formats:
dmg - macOS DMG image
pkg - macOS PKG installer
app-image - Application bundle (.app)
jpackage --type dmg --input lib --main-jar myapp.jar --name MyApp
jpackage --type pkg --input lib --main-jar myapp.jar --name MyApp
Essential Options
Application Identity
Name of the application and/or package. Can also use -n.jpackage --name MyApplication --input lib --main-jar app.jar
Version of the application and/or package.jpackage --name MyApp --app-version 1.2.3 --input lib --main-jar app.jar
Vendor of the application.jpackage --name MyApp --vendor "Example Corp" --input lib --main-jar app.jar
Description of the application.jpackage --name MyApp --description "My awesome application" \
--input lib --main-jar app.jar
Copyright for the application.jpackage --name MyApp --copyright "Copyright 2026 Example Corp" \
--input lib --main-jar app.jar
Path of the input directory containing files to package. Can also use -i.jpackage --input target/lib --main-jar myapp.jar --name MyApp
Path where generated output file is placed. Defaults to current directory. Can also use -d.jpackage --dest dist --input lib --main-jar app.jar --name MyApp
Type of package to create. Can also use -t.jpackage --type deb --input lib --main-jar app.jar --name MyApp
Application Content
Main JAR of the application; contains the main class.jpackage --input lib --main-jar myapp-1.0.jar --main-class com.example.Main
Qualified name of the application main class to execute.jpackage --input lib --main-jar app.jar --main-class com.example.Main
Main module and optionally main class of the application. Can also use -m.jpackage --module-path mods --module com.example.app/com.example.Main
Path where modules are located. Can also use -p.jpackage --module-path mods:$JAVA_HOME/jmods \
--module com.example.app \
--name MyApp
Runtime
Path of the predefined runtime image to use (created by jlink).# First create runtime with jlink
jlink --module-path mods --add-modules com.example.app --output app-runtime
# Then package it
jpackage --runtime-image app-runtime --name MyApp
Comma-separated list of modules to add.jpackage --module-path mods \
--add-modules com.example.app,java.sql,java.naming \
--name MyApp
Java Options
Options to pass to the Java runtime.jpackage --input lib --main-jar app.jar \
--java-options '-Xmx2g -Xms512m -Dapp.debug=true' \
--name MyApp
Command line arguments to pass to the main class if no arguments are specified by the launcher.jpackage --input lib --main-jar app.jar \
--arguments '--config=/etc/myapp/config.xml' \
--name MyApp
Options to pass to jlink when creating the runtime image.jpackage --module-path mods --module com.example.app \
--jlink-options '--strip-debug --compress=2' \
--name MyApp
Visual Customization
Path to the icon file for the application.
- Linux: PNG file
- Windows: ICO file
- macOS: ICNS file
jpackage --input lib --main-jar app.jar \
--icon resources/app-icon.png \
--name MyApp
Path to directory containing resources for the application.jpackage --input lib --main-jar app.jar \
--resource-dir resources \
--name MyApp
Path to the license file.jpackage --input lib --main-jar app.jar \
--license-file LICENSE.txt \
--name MyApp
Name for the Linux package (defaults to application name).jpackage --type deb --linux-package-name myapp-suite \
--input lib --main-jar app.jar
Maintainer for DEB package.jpackage --type deb --linux-deb-maintainer [email protected] \
--input lib --main-jar app.jar --name MyApp
Type of license for RPM package.jpackage --type rpm --linux-rpm-license-type "Apache-2.0" \
--input lib --main-jar app.jar --name MyApp
Application category for Linux package.jpackage --type deb --linux-app-category "Development" \
--input lib --main-jar app.jar --name MyApp
Create a desktop shortcut for the application.jpackage --type deb --linux-shortcut \
--input lib --main-jar app.jar --name MyApp
Add a dialog to enable the user to choose installation directory.jpackage --type msi --win-dir-chooser \
--input lib --main-jar app.jar --name MyApp
Add application to system menu.jpackage --type exe --win-menu \
--input lib --main-jar app.jar --name MyApp
Start Menu group for the application.jpackage --type exe --win-menu --win-menu-group "Example Apps" \
--input lib --main-jar app.jar --name MyApp
Create desktop shortcut for the application.jpackage --type msi --win-shortcut \
--input lib --main-jar app.jar --name MyApp
Request per-user installation.jpackage --type msi --win-per-user-install \
--input lib --main-jar app.jar --name MyApp
Unique identifier for macOS application.jpackage --type dmg --mac-package-identifier com.example.myapp \
--input lib --main-jar app.jar --name MyApp
Name of the application as it appears in the menu bar.jpackage --type pkg --mac-package-name "My Application" \
--input lib --main-jar app.jar --name MyApp
macOS application category.jpackage --type dmg --mac-app-category public.app-category.developer-tools \
--input lib --main-jar app.jar --name MyApp
Request signing of the package.jpackage --type pkg --mac-sign \
--mac-signing-key-user-name "Developer ID Application: Company" \
--input lib --main-jar app.jar --name MyApp
Common Usage Examples
Simple JAR Application
# Package a simple JAR application
jpackage --input target \
--name MyApp \
--main-jar myapp-1.0.jar \
--main-class com.example.Main \
--type deb \
--app-version 1.0
Modular Application
# Package a modular application
jpackage --type dmg \
--name MyModularApp \
--module-path mods:$JAVA_HOME/jmods \
--module com.example.myapp/com.example.Main \
--app-version 2.0 \
--vendor "Example Corp" \
--icon resources/app.icns
Using Custom Runtime
# Create custom runtime with jlink
jlink --module-path $JAVA_HOME/jmods:mods \
--add-modules com.example.app \
--strip-debug \
--compress 2 \
--output custom-runtime
# Package with the custom runtime
jpackage --runtime-image custom-runtime \
--name MyApp \
--type exe \
--app-version 1.0 \
--win-menu \
--win-shortcut
Production Package with All Options
jpackage --type deb \
--input target/lib \
--main-jar myapp-1.0.jar \
--main-class com.example.Application \
--name MyApplication \
--app-version 1.0.5 \
--vendor "Example Corporation" \
--description "My awesome Java application" \
--copyright "Copyright (c) 2026 Example Corp" \
--icon resources/icon.png \
--license-file LICENSE \
--java-options '-Xmx4g -XX:+UseG1GC' \
--arguments '--config=/etc/myapp/app.conf' \
--linux-package-name myapp \
--linux-deb-maintainer [email protected] \
--linux-app-category "Development" \
--linux-shortcut \
--dest dist
Multi-Launcher Application
jpackage --input lib \
--main-jar app.jar \
--main-class com.example.Main \
--name MyApp \
--add-launcher admin=admin-launcher.properties \
--add-launcher cli=cli-launcher.properties
Where admin-launcher.properties contains:
main-class=com.example.AdminMain
java-options=-Xmx1g
arguments=--admin-mode
Additional Options
Enable verbose output.jpackage --verbose --input lib --main-jar app.jar --name MyApp
Path to temporary directory for building.jpackage --temp /tmp/jpackage-build --input lib --main-jar app.jar
URL of the application’s home page.jpackage --about-url https://example.com/myapp \
--input lib --main-jar app.jar --name MyApp
Location of the predefined application image used to build an installable package.# First create app image
jpackage --type app-image --input lib --main-jar app.jar --name MyApp
# Then create installer from it
jpackage --type deb --app-image MyApp
File Associations
jpackage --input lib \
--main-jar editor.jar \
--file-associations file-assoc.properties
Where file-assoc.properties contains:
extension=txt
mime-type=text/plain
description=Text File
icon=text-icon.png
When packaging modular applications, jpackage can automatically invoke jlink to create an optimized runtime. Use --jlink-options to pass optimization flags like --strip-debug and --compress.
On Linux, you need either dpkg-deb (for DEB) or rpmbuild (for RPM) installed on your system. On macOS, code signing requires a valid Developer ID certificate.
Print help message. Can also use -h or -?.
Print version information.
Exit Codes
0: Successful packaging
1: Packaging failed
See Also