Java 9 ने मॉड्यूल सिस्टम (Project Jigsaw) का समर्थन करने के लिए क्लास लोडर आर्किटेक्चर में मूलभूत परिवर्तन पेश किए। पारंपरिक तीन-स्तरीय पदानुक्रम (बूटस्ट्रैप → एक्सटेंशन → सिस्टम/एप्लिकेशन) को पुनर्गठित किया गया है।
Java 8 बनाम Java 9+ क्लास लोडर पदानुक्रम
| Java 8 | Java 9+ | परिवर्तन |
|---|---|---|
| बूटस्ट्रैप क्लास लोडर | बूटस्ट्रैप क्लास लोडर | अपरिवर्तित - देशी, कोर क्लासेस लोड करता है |
| एक्सटेंशन क्लास लोडर | प्लेटफॉर्म क्लास लोडर | नाम बदला, अब आंतरिक क्लास (URLClassLoader नहीं) |
| सिस्टम/एप्लिकेशन क्लास लोडर | एप्लिकेशन क्लास लोडर | अब आंतरिक क्लास, मॉड्यूल के लिए डिफ़ॉल्ट लोडर |
मुख्य परिवर्तन
1. सिस्टम क्लास लोडर अब URLClassLoader नहीं है
// Java 8
ClassLoader sysLoader = ClassLoader.getSystemClassLoader();
System.out.println(sysLoader.getClass().getName());
// आउटपुट: java.net.URLClassLoader
// Java 9+
ClassLoader sysLoader = ClassLoader.getSystemClassLoader();
System.out.println(sysLoader.getClass().getName());
// आउटपुट: jdk.internal.loader.ClassLoaders$AppClassLoader
2. एक्सटेंशन → प्लेटफॉर्म क्लास लोडर
- नाम बदलकर "प्लेटफॉर्म क्लास लोडर" किया गया
- Java SE प्लेटफॉर्म मॉड्यूल्स लोड करता है
- JCP मॉड्यूल्स भी लोड करता है जो Java SE का हिस्सा नहीं हैं
- URLClassLoader नहीं - आंतरिक कार्यान्वयन
3. मॉड्यूल जागरूकता
- एप्लिकेशन क्लास लोडर नामित मॉड्यूल्स में कक्षाओं के लिए डिफ़ॉल्ट लोडर है
- क्लास लोडर अब मॉड्यूल सीमाओं का सम्मान करते हैं
ClassLoader::loadClassअनाम मॉड्यूल के लिए काम करता है
क्लास लोडर निरीक्षण उदाहरण
public class ClassLoaderInspector {
public static void main(String[] args) throws ClassNotFoundException {
System.out.println("=== क्लास लोडर पदानुक्रम ===");
// वर्तमान कक्षा का क्लास लोडर
ClassLoader appCL = ClassLoaderInspector.class.getClassLoader();
System.out.println("एप्लिकेशन CL: " + appCL);
System.out.println(" वर्ग: " + appCL.getClass().getName());
// पैरेंट: प्लेटफॉर्म CL
ClassLoader platformCL = appCL.getParent();
System.out.println("प्लेटफॉर्म CL: " + platformCL);
System.out.println(" वर्ग: " + (platformCL != null ? platformCL.getClass().getName() : "null"));
// पैरेंट: बूटस्ट्रैप CL
ClassLoader bootstrapCL = platformCL != null ? platformCL.getParent() : null;
System.out.println("बूटस्ट्रैप CL: " + bootstrapCL); // null
System.out.println("\n=== विशिष्ट कक्षाओं के क्लास लोडर ===");
// उपयोगकर्ता कक्षा (एप्लिकेशन मॉड्यूल)
System.out.println("ClassLoaderInspector: " +
ClassLoaderInspector.class.getClassLoader());
// प्लेटफॉर्म कक्षा (java.sql)
System.out.println("java.sql.SQLPermission: " +
java.sql.SQLPermission.class.getClassLoader());
// बूटस्ट्रैप कक्षा (java.util)
System.out.println("java.util.LinkedList: " +
java.util.LinkedList.class.getClassLoader()); // null = बूटस्ट्रैप
// JDK आंतरिक (प्लेटफॉर्म)
System.out.println("jdk.internal.loader.ClassLoaders: " +
jdk.internal.loader.ClassLoaders.class.getClassLoader());
}
}
आउटपुट उदाहरण
=== क्लास लोडर पदानुक्रम === एप्लिकेशन CL: jdk.internal.loader.ClassLoaders$AppClassLoader@504bae78 वर्ग: jdk.internal.loader.ClassLoaders$AppClassLoader प्लेटफॉर्म CL: jdk.internal.loader.ClassLoaders$PlatformClassLoader@299a06ac वर्ग: jdk.internal.loader.ClassLoaders$PlatformClassLoader बूटस्ट्रैप CL: null === विशिष्ट कक्षाओं के क्लास लोडर === ClassLoaderInspector: jdk.internal.loader.ClassLoaders$AppClassLoader@504bae78 java.sql.SQLPermission: jdk.internal.loader.ClassLoaders$PlatformClassLoader@299a06ac java.util.LinkedList: null jdk.internal.loader.ClassLoaders: jdk.internal.loader.ClassLoaders$PlatformClassLoader@299a06ac
माइग्रेशन प्रभाव और समाधान
समस्या 1: बूटस्ट्रैप को पैरेंट के रूप में मानने वाला कोड
// Java 8 पैटर्न - अब टूटा हुआ
ClassLoader cl = new MyClassLoader(null); // null = बूटस्ट्रैप
// Java 9+ फिक्स: प्लेटफॉर्म क्लास लोडर का उपयोग करें
ClassLoader platformCL = ClassLoader.getPlatformClassLoader();
ClassLoader cl = new MyClassLoader(platformCL);
समस्या 2: -Xbootclasspath/a उपयोग
// Java 8: बूटस्ट्रैप क्लासपथ में जोड़ें
java -Xbootclasspath/a:/path/to/jar MyApp
// Java 9+: --patch-module या मॉड्यूल पथ का उपयोग करें
java --patch-module java.base=/path/to/jar MyApp
// या
java --module-path /path/to/modules -m my.module
समस्या 3: URLClassLoader कास्टिंग
// Java 8 - काम करता था
URLClassLoader ucl = (URLClassLoader) ClassLoader.getSystemClassLoader();
ucl.addURL(new URL("file:/path/to.jar"));
// Java 9+ - ClassCastException फेंकता है!
// समाधान: मॉड्यूल सिस्टम, लेयर्ड आर्किटेक्चर, या जार को क्लासपथ पर रखें
मॉड्यूल के साथ क्लास लोडर
import java.lang.module.ModuleFinder;
import java.lang.module.ModuleReference;
import java.util.Set;
public class ModuleClassLoaders {
public static void main(String[] args) {
// बूट लेयर में सभी मॉड्यूल्स और उनके क्लास लोडर्स सूचीबद्ध करें
ModuleLayer.boot().modules().forEach(module -> {
ClassLoader cl = module.getClassLoader();
String clName = (cl == null) ? "बूटस्ट्रैप" : cl.getClass().getSimpleName();
System.out.printf("%-15s: %s%n", clName, module.getName());
});
}
}
आउटपुट नमूना
बूटस्ट्रैप : java.base प्लेटफॉर्म : java.sql प्लेटफॉर्म : java.logging एप्लिकेशन : com.myapp बूटस्ट्रैप : jdk.management ...
सर्वोत्तम अभ्यास Java 9+
- क्लास लोडर कास्ट न करें: आंतरिक कार्यान्वयन विवरण पर भरोसा न करें
- क्लासपथ पर मॉड्यूल पथ पसंद करें: मॉड्यूलर एप्लिकेशन के लिए
- ClassLoader.getPlatformClassLoader() का उपयोग करें प्लेटफॉर्म कक्षाओं के लिए
- --patch-module का उपयोग करें JDK कक्षाओं को पैच/ओवरराइड करने के लिए
- जेएनआई/नेटिव लाइब्रेरी: अभी भी
java.library.pathयाSystem.load()का उपयोग करते हैं
सारांश
Java 9 के क्लास लोडर परिवर्तन मॉड्यूलर एनकैप्सुलेशन को लागू करते हैं। मुख्य निष्कर्ष: URLClassLoader कास्टिंग टूट गई है, एक्सटेंशन CL अब प्लेटफॉर्म CL है, और एप्लिकेशन CL मॉड्यूल-जागरूक है। मॉड्यूल पथ, --patch-module, और मानक API का उपयोग करके माइग्रेट करें।