ว่าด้วย Java Class Loader
Java Developer อย่างผมยังไม่เข้าใจว่า JVM (Java Virtual Machine) มันโหลด class เข้าไปทำงานได้อย่างไรน๊าา อ่อใช้ Java Class Loader นี่เอง ในบทความนี้จะมาทำความเข้าใจไปด้วยกันว่าไอ้ Java Class Loader เนี๊ยะมันทำงานอย่างไร เพื่อที่จะเป็น Java Developer ที่เข้าใจใน Java มากขึ้น
Java Class Loader
เป็นส่วนหนึ่งของ JRE (Java Runtime Environment) ที่โหลด Java Class ต่างๆ ในขณะทำงาน (Dynamically) ให้กับ JVM โดยทั่วไปแล้ว Class จะถูกโหลดได้ตามความต้องการ (On Demand) เท่านั้น ซึ่งระบบ Java runtime system ไม่จำเป็นต้องรู้เกี่ยวกับ file sytem เพราะใช้ Class Loader
ซึ่ง Java Class จะไม่จำเป็นต้องโหลดทั้งหมดในครั้งเดียว แต่เมื่อจำเป็นต้องใช้ classใดๆ โดยแอพพลิเคชัน ถึงคราวที่ Java Class Loader จะถูกเรียกใช้โดย JRE และ Class Loader จะโหลด class นั้นๆ เข้าไปในหน่วยความจำ dynamic
โดยมีหลักการของ Class Loader ดังนี้
- Delegate Model — จะส่งต่อการร้องขอการโหลด Class ไปยัง Parent Class Loader โดยที่มันจะโหลด Class ก็ต่อเมื่อ Class Loader แม่ (Parent) หาไม่เจอ
- Visibility Principle — จะอนุญาติให้ Class Loader ลูก (Child) มองเห็น Class ที่ถูกโหลดแล้วของ Class Loader แม่ แต่จะไม่ให้ Class Loader แม่ มองเห็นของลูก
- Uniqueness Properties — จะอนุญาติให้โหลด Class ใดๆ ได้เพียงครั้งเดียว โดยอาศัย Delegate Model
Type of Class Loader
Class ทั้งหมดไม่ได้ถูกโหลดด้วย Class Loader ในเพียงครั้งเดียว แต่จะขึ้นอยู่กับชนิด (Type) ของ class นั้นๆ และที่อยู่ (Path) ของ class โดย Class Loader จะโหลด class ใดๆ ที่ถูกพิจารณาแล้วว่าสมควรโหลด ซึ่งถ้า Class Loader หา class ใดๆ ไม่เจอก็จะ throw NoClassDefFoundError หรือ ClassNotFoundException (บางท่านอาจจะเจอบ่อยๆ อิอิ)
Java Class Loader มี 3 ประเภท คือ
- Bootstrap Class Loader — เป็น machine close ที่จะถูกเรียกใช้ (kickstart) ตอนแรกของ JVM ซึ่งแน่นอนไม่ใช้ Java code โดยหน้าที่ของมันคือโหลด pure Java Class Loader เริ่มแรกที่เป็น Java code ให้ทำงาน ซึ่งจะโหลดจาก rt.java
- Extension Class Loader — เป็นลูกของ Bootstrap Class Loader โดยที่จะโหลดส่วนขยาย (Extension) ของ Core Java Classes จาก JRE extension library ซึ่งจะโหลดจาก /jre/lib/ext หรือ directory อื่นๆ ที่ระบุไว้กับตัวแปร java.ext.dirs
- System Class Loader — โดยที่จะโหลด class ของ Application ที่เจอใน environment variable CLASSPATH, -class-path, หรือ -cp command line option ซึ่ง System Class Loader นี้เป็นลูกของ Extension Class Loader
How It’s work
เมื่อเราทราบว่าใน Java มีกี่ประเถท ก็จะมาดูว่า Java Class Laoder ทำงานอย่างไร
เมื่อ JVM ร้องขอสำหรับ class ใดๆ มันจะใช้ loadClass()
method ซึ่งเป็น method ของ ClassLoader class ด้วย path ของ class เป็น input และจะใช้ findLoadedClass()
method อีกทีเพื่อตรวจสอบว่า class ที่ต้องการโหลดแล้วหรือไม่ เป็นการป้องกันการโหลด class เดิมซ้ำๆ หลายครั้ง
ถ้า class ใดๆ โหลดมาแล้ว มันจะ delegate request ไปยัง Class Loader แม่ เพื่อโหลด class นั้น แต่ถ้ายังไม่โหลด class ใดๆ จะใช้ findClass()
method เพื่อค้นหา class ในระบบ
รูปด้านล่างนี้จะแสดงให้ภาพมากขึ้นเห็นว่า Class Loader ทำงานอย่างไร
ลองเขียน class ง่ายๆ เพื่อดูลำดับขั้นของ Class Loader เมื่อรัน application จะเห็นได้ว่า ClassLoaderTest อยู่ใน AppClassLoader
(Application Class Loader) แต่ Class Loader แม่เป็น ExtClassLoader
(External Class Loader) และแสดง Class Loader แม่ของ ExtClassLoader เป็น null
เนื่องจากเป็น Bootstrap Class Loader ที่เป็น machine code ทำให้ JVM มอกว่าเป็น Null value
Application Class Loader: sun.misc.Launcher$AppClassLoader@18b4aac2
Extension Class Loader: sun.misc.Launcher$ExtClassLoader@61bbe9ba
BootStrap Class Loader: null
สรุป
จากการที่ได้เรียนรู้การทำงานของ Java Class Loader นี้ จะเห็นได้ว่า Class Loader แบ่งออกเป็น 3 ประเภท Bootstrap Class Loader ที่เริ่มทำงานตั้งแต่ JVM ทำงาน, Extension Class Loader ที่โหลด Java extension และ Application Class Loader ที่จะโหลด class ของ Application ของเรา และตัวอย่างง่ายๆ ของลำดับขั้นของ Class Loader ต่างๆ