ทุกโปรแกรม Java รันบน Java Virtual Machine (JVM) หลัง compile คลาส Java จะกลายเป็น platform-independent bytecode และเก็บเป็นไฟล์ .class เมื่อต้องการใช้ ClassLoader จะโหลดคลาสเข้า memory คลาสจะถูกนำเข้าสู่ Java environment เมื่อถูกอ้างอิงโดยชื่อ การโหลดคลาสทำโดย class loader เมื่อคลาสเริ่มรัน main() method เป็นจุดเริ่มต้น
การเปลี่ยนแปลงเล็กน้อยของ Class Loaders ใน Java 9
- System class loader ไม่ใช่ instance ของ URLClassLoader อีกต่อไป เป็น internal class แทน เป็น default loader สำหรับคลาสใน modules
- Extension class loader เปลี่ยนชื่อเป็น Platform class loader คลาสใน Java SE Platform มองเห็นได้ผ่าน platform class loader คลาสใน modules ภายใต้ Java Community Process แต่ไม่ใช่ส่วนของ Java SE platform ก็มองเห็นได้ผ่าน platform class loader เช่นกัน
- Applications ไม่ควรพึ่งพา class loader ที่กำหนดว่าคลาสไหนใน Java SE Platform ถูก define โดย platform class loader ส่วนอื่นโดย bootstrap class loader
- ถ้าโค้ดเดิมสร้าง class loader ด้วย bootstrap class loader เป็น parent ต้องเปลี่ยนมาใช้ platform class loader เป็น parent แทน
- Platform class loader ไม่ใช่ instance ของ URLClassLoader เป็น internal class
- Bootstrap class loader เป็น built-in class loader ของ JVM กำหนดคลาสของ critical modules เช่น java.base แอปพลิเคชันที่ deploy ด้วย
-Xbootclasspath/aหรือสร้าง class loader ด้วยnullเป็น parent อาจต้องปรับเปลี่ยน
ตัวอย่างโค้ด
public class ClassLoaderTest {
public static void main(String args[]) {
System.out.println("Class Loader Test");
ClassLoaderTest test = new ClassLoaderTest();
try {
test.showClassLoaders();
} catch(ClassNotFoundException cnfe) {
System.out.println(cnfe.getMessage());
}
}
public void showClassLoaders() throws ClassNotFoundException {
System.out.println("Classloader of this class: " + ClassLoaderTest.class.getClassLoader());
System.out.println("Classloader of Permission: " + java.sql.SQLPermission.class.getClassLoader());
System.out.println("Classloader of LinkedList: " + java.util.LinkedList.class.getClassLoader());
}
}
ผลลัพธ์
Class Loader Test
Classloader of this class: jdk.internal.loader.ClassLoaders$AppClassLoader@504bae78
Classloader of Permission: jdk.internal.loader.ClassLoaders$PlatformClassLoader@299a06ac
Classloader of LinkedList: null
คำอธิบายผลลัพธ์
- AppClassLoader (jdk.internal.loader.ClassLoaders$AppClassLoader) - โหลด application classes (system class loader ใหม่)
- PlatformClassLoader (jdk.internal.loader.ClassLoaders$PlatformClassLoader) - โหลด platform classes เช่น java.sql.SQLPermission
- null - แสดงว่าโหลดโดย Bootstrap class loader (builtin classes เช่น java.util.LinkedList, java.lang.Object)
Class Loader Hierarchy ใน Java 9
Bootstrap Class Loader (null)
↑ parent
Platform Class Loader (internal class)
↑ parent
Application Class Loader (AppClassLoader - internal class)
↑ parent
Custom Class Loaders...
ผลกระทบต่อการ Migration
- โค้ดที่ใช้
ClassLoader.getSystemClassLoader()ยังทำงานได้ แต่คืนค่า AppClassLoader (internal class) - โค้ดที่ cast เป็น
URLClassLoaderอาจล้มเหลว (ClassCastException) - การใช้
-Xbootclasspath/aถูกจำกัด ควรใช้--upgrade-module-pathหรือ--patch-moduleแทน