How to Shrink a Java Runtime Image from 400 MB to 28 MB with JMOD and jlink
This tutorial walks through creating a simple Java module, packaging it into a JMOD file, and using jlink to build a custom runtime image that shrinks the size from roughly 400 MB to 28 MB, then demonstrates compiling, inspecting, and running the application.
1. Introduction to JMOD
JMOD, introduced in Java 9, is a new file format (extension .jmod) designed for the module system (Project Jigsaw). It packages compiled code, configuration files, native libraries, and legal resources. Unlike traditional JAR files, which are intended for runtime, JMOD targets compile‑time and link‑time and cannot be placed directly on the classpath or executed by the JVM.
2. Building a Simple Modular Application
First, a minimal Java class is created:
package com.pack;
import java.util.logging.*;
public class App {
private static final Logger LOG = Logger.getLogger(App.class.getName());
public static void main(String[] args) {
LOG.info("Spring Boot3实战案例300讲!!!");
}
}A module-info.java file is added to declare the module and its dependency on java.logging:
module com.pack.demo {
requires java.logging;
}The source files are compiled with a batch script that places the class files into an output directory:
for /r %%i in (*.java) do javac -d output %%i3. Creating a JMOD File
The compiled module is packaged into a JMOD file using the jmod create command:
jmod create --class-path output/ \
--main-class com.pack.App \
--module-version 1.0.0 \
-p output app.jmodThis command creates app.jmod in the current directory. The JMOD can be inspected with:
jmod describe app.jmod
[email protected]
requires java.base mandated
requires java.logging
contains com.pack
main-class com.pack.AppThe output confirms that the module and its metadata are correctly encapsulated and ready for linking.
4. Building a Custom Runtime with jlink
Using jlink, a minimal runtime image is generated:
jlink --module-path %JAVA_HOME%/jmods;./app.jmod \
--add-modules com.pack.demo \
--launcher app=com.pack.demo/com.pack.App \
--strip-debug \
--no-header-files \
--no-man-pages \
--output rtKey options:
--module-path : tells jlink where to find the standard JDK modules and the custom app.jmod.
--add-modules : specifies the root module to include in the image.
--launcher : creates a launch script named app that runs com.pack.App.
--strip-debug , --no-header-files , --no-man-pages : remove optional content to reduce size.
The command creates a new directory rt that contains the custom runtime.
The size of the rt directory is shown to be dramatically smaller than a full JDK installation (which typically occupies 300–400 MB).
5. Verifying the Custom Runtime
Listing the modules available in the custom runtime confirms that only the required modules are present:
PS E:\java_jmod> ./rt/bin/java --list-modules
[email protected]
[email protected]
[email protected]Running the application with the custom launcher produces the expected log output:
PS E:\java_workspace\java_jmod> ./rt/bin/app
Jul 01, 2026 7:55:41 AM com.pack.App main
信息: Spring Boot3实战案例300讲!!!The application runs successfully using the trimmed runtime, demonstrating that JMOD and jlink can reduce a Java image from roughly 400 MB to 28 MB while preserving functionality.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
