Java Modules (JPMS) & Modern Packaging
Java Platform Module System ও আধুনিক packaging
1. The Problem JPMS Solves
Before Java 9, the JDK itself was one giant rt.jar — every Android app, every Hello-World,
shipped the whole thing. Worse, packages could be accessed from anywhere. Java 9 introduced
the Java Platform Module System (JPMS): a formal way to split the JDK and your own
code into modules that declare exactly what they export and what they require.
rt.jar ছিল — ছোট Hello-World অ্যাপেও পুরোটাই যেতো। Package যেকোনো জায়গা থেকে access করা যেতো। Java 9-এ এলো Java Platform Module System (JPMS) — JDK এবং আপনার কোড module-এ ভাগ করা, যেখানে প্রতিটি module স্পষ্টভাবে বলে দেয় কী export করে এবং কী require করে।
2. Anatomy of module-info.java
Every JPMS module is identified by a single file in its root: module-info.java. The file is
short and declarative — it lists what the module exports, what it requires, and the
services it uses or provides.
module-info.java। এটি ছোট ও declarative — কোন package export করবে, কোন module require করবে, এবং কোন service use বা provide করবে।
// Module: com.abcltech.payments
module com.abcltech.payments {
// Depends on two other modules
requires java.net.http;
requires transitive com.abcltech.core;
// Public API — only these packages are visible to others
exports com.abcltech.payments.api;
// Internal — not exported (but opened for reflection)
opens com.abcltech.payments.internal to com.fasterxml.jackson.databind;
// Service consumer / producer
uses com.abcltech.payments.spi.PaymentProvider;
provides com.abcltech.payments.spi.PaymentProvider
with com.abcltech.payments.bkash.BkashProvider;
}
| Keyword | Means | বাংলায় |
|---|---|---|
requires | This module depends on that module. | এই module ঐ module-এর উপর নির্ভরশীল। |
requires transitive | Passes the dep through to consumers. | পরবর্তী consumer-এও dependency পৌঁছায়। |
exports | Makes a package public API. | একটি package-কে public API করে। |
opens | Allows deep reflection (for frameworks). | Reflection access দেয় (framework-এর জন্য)। |
uses / provides | Service-loader SPI consumer / producer. | ServiceLoader-এর SPI consumer / producer। |
3. Modules in a Real App
4. jlink — Ship Just the JDK You Need
Once your app is modular, jlink can generate a custom JDK runtime containing
only the platform modules you actually use. A Hello-World runtime can drop from ~180 MB down to ~40 MB.
jlink একটি custom JDK runtime বানিয়ে দেয় — শুধু যা যা লাগছে। Hello-World-এর জন্য পুরো JDK (~১৮০ MB) না নিয়ে ছোট ~৪০ MB runtime-ই যথেষ্ট।
# 1. Compile into a modular JAR
javac -d out --module-source-path src $(find src -name "*.java")
jar --create --file payments.jar -C out/com.abcltech.payments .
# 2. jlink — slim, custom runtime containing only our modules
jlink \
--module-path $JAVA_HOME/jmods:. \
--add-modules com.abcltech.payments \
--launcher run=com.abcltech.payments/com.abcltech.payments.Main \
--compress=2 --no-header-files --no-man-pages \
--output build/slim-runtime
# 3. Run it — no separate JDK needed on target
./build/slim-runtime/bin/run
4.1 jpackage — Native Installers
jpackage (since Java 14) wraps a jlink runtime + your app into a native installer:
.msi on Windows, .dmg on macOS, .deb/.rpm on Linux.
Users do not need a pre-installed JDK.
jpackage (Java 14+) jlink-এর runtime এবং আপনার app একসাথে করে native installer তৈরি করে — Windows-এ .msi, macOS-এ .dmg, Linux-এ .deb/.rpm। User-এর আলাদা JDK install করতে হয় না।
5. A Runnable Peek at Module Info
Even in a non-modular sandbox, the Module API works. Every class belongs to a module — when
you are not using JPMS, it is the "unnamed module". Run this to see which modules your classes
live in.
class Main {
public static void main(String[] args) {
Module m1 = String.class.getModule();
Module m2 = Main.class.getModule();
Module m3 = java.util.ArrayList.class.getModule();
System.out.println("String lives in: " + m1);
System.out.println("Main lives in: " + (m2.isNamed() ? m2 : "(unnamed module)"));
System.out.println("ArrayList lives in: " + m3);
System.out.println("\nJDK reports " + ModuleLayer.boot().modules().size() + " boot-layer modules.");
}
}
6. The Honest State of Modules
✅ Where JPMS Shines
- Desktop apps shipped with jlink/jpackage
- Large corporate apps that want strict encapsulation
- Custom embedded JDK builds (IoT, edge)
- Publishing libraries with a clear public surface
⚠️ Where It Lags
- Many older libraries still aren't modular
- Automatic-module naming can be fragile
- Spring Boot ecosystem leans on classpath, not modulepath
- Team ergonomics — steeper learning curve
jlink/jpackage benefits
for a client-facing installer. That's a pragmatic choice, not a failure of the module system.
বাংলাদেশের Spring-নির্ভর fintech-এ অনেকেই এখনো classpath-এ কাজ করে, আর শুধু jlink/jpackage লাগলেই JPMS-এ যায়। এটা একটি বাস্তব সিদ্ধান্ত।
7. Vocabulary
| Term | Meaning | বাংলায় |
|---|---|---|
| JPMS | Java Platform Module System, since Java 9. | Java 9-এ আসা module system। |
| Module descriptor | The module-info.java file. | module-info.java ফাইল। |
| Automatic module | A plain JAR used as a module — name derived from filename. | Non-modular JAR-কে auto module হিসেবে গণ্য। |
| Unnamed module | Everything on the classpath. | Classpath-এ থাকা সব কোড। |
| jlink | Creates a custom JDK runtime image. | Custom JDK runtime তৈরি করে। |
| jpackage | Creates native installers. | Native installer বানায় (.msi/.dmg/.deb)। |
8. Practice Problems
-
Write a
module-info.javafor a hypotheticalcom.abcltech.utilsmodule that depends onjava.loggingand exports a packagecom.abcltech.utils.text.একটিmodule-info.javaলিখুন —com.abcltech.utilsmodule,java.logging-এর উপর নির্ভরশীল,com.abcltech.utils.textexport করে।✨ Show Answer
module-info.javamodule com.abcltech.utils { requires java.logging; exports com.abcltech.utils.text; } -
Write a Java program that prints
java.base,java.sql, and your own class's module names.একটি Java program লিখুন যাjava.base,java.sqlও আপনার নিজের class-এর module print করবে।✨ Show Answer
Main.javaclass Main { public static void main(String[] args) throws Exception { System.out.println("String -> " + String.class.getModule()); System.out.println("Connection -> " + Class.forName("java.sql.Connection").getModule()); System.out.println("Main -> " + Main.class.getModule()); } } -
Explain the difference between
exportsandopens.exportsএবংopens-এর পার্থক্য ব্যাখ্যা করুন।✨ Show Answer
Answer:
exportsmakes the package visible at compile time AND for normal runtime access — other modules canimportand call its public types.opensadditionally permits deep reflection (including private members) at runtime, but does not permit compile-time imports. Frameworks like Hibernate and Jackson needopensto read your private fields via reflection; ordinary consumers only needexports. -
You're shipping a small JavaFX desktop app to Bangladeshi users who do not have Java installed. Which tool creates the
.msiinstaller?একটি JavaFX desktop app ব্যবহারকারীদের কাছে পাঠাতে চান — তাদের কাছে Java নেই। কোন টুল দিয়ে.msiinstaller বানাবেন?✨ Show Answer
Answer:
jpackage. It bundles your application, the JavaFX modules, and a slimmed-down JDK produced byjlinkinto a single native installer. The end user just double-clicks the.msi— no separate JDK, no setup steps. -
Write a runnable program that lists every "java.*" module currently loaded in the boot layer and counts them.একটি program লিখুন যা boot layer-এ লোড হওয়া সব
java.*module তালিকা করবে এবং সংখ্যা গুণে দেখাবে।✨ Show Answer
Main.javaclass Main { public static void main(String[] args) { long n = ModuleLayer.boot().modules().stream() .map(Module::getName) .filter(name -> name.startsWith("java.")) .peek(System.out::println) .count(); System.out.println("\nTotal java.* modules: " + n); } }
Summary — Module 46
JPMS gives Java a real module system — explicit requires, explicit exports, and
strong encapsulation. It pairs beautifully with jlink (custom runtimes) and
jpackage (native installers). Adoption is uneven, but for desktop apps, libraries, and
embedded JDK builds the story is excellent.
requires, স্পষ্ট exports ও কঠোর encapsulation। jlink (custom runtime) ও jpackage (native installer)-এর সাথে চমৎকার। Adoption অসম হলেও, desktop app, library ও embedded JDK build-এ দারুণ কাজ করে।