กลับไปหน้าบทความ

อ่าน 4 นาที

ตัวโหลดคลาส Java

ตัว โหลดคลาส Java ซึ่งเป็นส่วนหนึ่งของ สภาพแวดล้อมรันไทม์ Java จะ โหลด คลาส Java ลงใน เครื่องเสมือน Java แบบ ไดนามิก [ 1 ] [ 2 ] โดยปกติแล้วคลาสจะถูกโหลดเฉพาะ เมื่อมีการร้องขอ...

ตัวโหลดคลาส Java

ตัวโหลดคลาส Javaซึ่งเป็นส่วนหนึ่งของสภาพแวดล้อมรันไทม์ Javaจะโหลดคลาส Javaลงในเครื่องเสมือน Java แบบไดนามิก[ 1 ] [ 2 ]โดยปกติแล้วคลาสจะถูกโหลดเฉพาะเมื่อมีการร้องขอ เท่านั้น เครื่องเสมือนจะโหลดเฉพาะไฟล์คลาสที่จำเป็นสำหรับการเรียกใช้โปรแกรม[ 3 ]ระบบรันไทม์ Java ไม่จำเป็นต้องรู้เกี่ยวกับไฟล์และระบบไฟล์ เนื่องจากหน้าที่นี้ถูกมอบหมายให้กับตัวโหลดคลาส

ไลบรารีซอฟต์แวร์คือชุดของโค้ดวัตถุ ที่เกี่ยวข้องกัน ในภาษาจาวาไลบรารีมักจะถูกบรรจุอยู่ในไฟล์ JARไลบรารีสามารถมีวัตถุประเภทต่างๆ ได้ ประเภทของวัตถุที่สำคัญที่สุดที่อยู่ในไฟล์ JAR คือคลาสของจาวาคลาสสามารถคิดได้ว่าเป็นหน่วยของโค้ดที่มีชื่อ ตัวโหลดคลาสมีหน้าที่ในการค้นหาไลบรารี อ่านเนื้อหา และโหลดคลาสที่อยู่ในไลบรารี การโหลดนี้มักจะทำ "ตามความต้องการ" กล่าวคือจะไม่เกิดขึ้นจนกว่าโปรแกรมจะเรียกใช้คลาส คลาสที่มีชื่อที่กำหนดสามารถโหลดได้เพียงครั้งเดียวโดยตัวโหลดคลาสที่กำหนดเท่านั้น

แต่ละคลาส Java จะต้องถูกโหลดโดยคลาสโหลดเดอร์[ 4 ] [ 5 ]นอกจากนี้ โปรแกรม Javaอาจใช้ไลบรารีภายนอก (นั่นคือ ไลบรารีที่เขียนและจัดหาโดยบุคคลอื่นที่ไม่ใช่ผู้เขียนโปรแกรม) หรืออาจประกอบขึ้นจากไลบรารีจำนวนหนึ่งอย่างน้อยบางส่วน

เมื่อ JVM เริ่มทำงาน จะมีการใช้คลาสโหลดเดอร์ 3 ตัว: [ 6 ] [ 7 ] [ 3 ]

  1. ตัวโหลดคลาส Bootstrap
  2. ตัวโหลดคลาสส่วนขยาย
  3. ตัวโหลดคลาสระบบ

ตัวโหลดคลาสบูตสแตรปจะโหลดไลบรารี Java หลัก[ fn 1 ]ที่อยู่ใน ไดเร็กทอรี <JAVA_HOME>/jre/lib(หรือ<JAVA_HOME>/jmods>สำหรับ Java 9 ขึ้นไป) ตัวโหลดคลาสนี้ซึ่งเป็นส่วนหนึ่งของ JVM หลัก เขียนด้วยโค้ดเนทีฟ ตัวโหลดคลาสบูตสแตรปไม่ได้เชื่อมโยงกับClassLoaderวัตถุ ใดๆ [ 3 ]ตัวอย่างเช่นส่งคืน. [ 3 ]StringBuilder.class.getClassLoader()null

ตัวโหลดคลาสส่วนขยายจะโหลดโค้ดในไดเร็กทอรีส่วนขยาย ( <JAVA_HOME>/jre/lib/ext, [ 6 ]หรือไดเร็กทอรีอื่นใดที่ระบุโดยjava.ext.dirsคุณสมบัติของระบบ)

ตัวโหลดคลาสของระบบจะโหลดโค้ดที่พบในjava.class.pathซึ่งแมปกับCLASSPATHตัวแปรสภาพแวดล้อม

ตัวโหลดคลาสที่ผู้ใช้กำหนดเอง

ตัวโหลดคลาสของ Java เขียนด้วยภาษา Java ดังนั้นจึงสามารถสร้างตัวโหลดคลาสแบบกำหนดเองได้โดยไม่ต้องเข้าใจรายละเอียดปลีกย่อยของ Java Virtual Machine นอกจากตัวโหลดคลาส Bootstrap แล้ว ตัวโหลดคลาสของ Java ทุกตัวจะมีตัวโหลดคลาสแม่[ 8 ]ตัวโหลดคลาสแม่จะถูกกำหนดเมื่อมีการสร้างอินสแตนซ์ของตัวโหลดคลาสใหม่หรือตั้งค่าเป็นตัวโหลดคลาสเริ่มต้นของระบบของเครื่องเสมือน

สิ่งนี้ทำให้สามารถทำสิ่งต่างๆ ได้ (ตัวอย่างเช่น):

  • เพื่อโหลดหรือยกเลิกการโหลดคลาสในระหว่างการทำงาน (ตัวอย่างเช่น การโหลดไลบรารีแบบไดนามิกในระหว่างการทำงาน แม้กระทั่งจาก ทรัพยากร HTTP ) นี่เป็นคุณสมบัติที่สำคัญสำหรับ:
    • การนำภาษาสคริปต์มาใช้ เช่นJython
    • การใช้Bean Builders
    • อนุญาตให้ผู้ใช้สามารถกำหนดส่วนขยาย ได้เอง
    • อนุญาตให้เนมสเปซ หลายๆ ตัว สามารถสื่อสารกันได้ นี่เป็นหนึ่งในพื้นฐานของ โปรโตคอล CORBA / RMIเป็นต้น
  • เพื่อเปลี่ยนวิธี การโหลด ไบต์โค้ด (ตัวอย่างเช่น สามารถใช้ไบต์โค้ดคลาส Java ที่เข้ารหัสได้[ 9 ] )
  • เพื่อแก้ไขไบต์โค้ดที่โหลดมา (ตัวอย่างเช่น สำหรับการผสานแง่มุมต่างๆ ในระหว่างการโหลดเมื่อใช้การเขียนโปรแกรมเชิงแง่มุม )

ตัวโหลดคลาสในจาการ์ตา EE

โดยทั่วไปเซิร์ฟเวอร์แอปพลิเคชันJakarta EE (เดิมคือ Java EE และ J2EE) จะโหลดคลาสจากไฟล์ WARหรือEAR ที่ถูกใช้งาน โดยใช้ตัวโหลดคลาสแบบต้นไม้ ซึ่งแยกแอปพลิเคชันออกจากแอปพลิเคชันอื่น แต่ใช้คลาสร่วมกันระหว่างโมดูลที่ถูกใช้งาน โดยทั่วไปแล้ว " คอนเทนเนอร์เซิร์ฟเล็ต " จะถูกนำไปใช้ในรูปแบบของตัวโหลดคลาสหลายตัว[ 5 ] [ 10 ]

นรก JAR

JAR hell เป็นคำที่คล้ายกับDLL hellซึ่งใช้เพื่ออธิบายวิธีการต่างๆ ที่กระบวนการโหลดคลาสอาจล้มเหลว[ 11 ] JAR hell สามารถเกิดขึ้นได้ 3 วิธี ได้แก่:

  • การติดตั้งไลบรารีสองเวอร์ชันที่แตกต่างกันโดยไม่ได้ตั้งใจในระบบ ระบบจะไม่ถือว่านี่เป็นข้อผิดพลาด แต่ระบบจะโหลดคลาสจากไลบรารีใดไลบรารีหนึ่ง การเพิ่มไลบรารีใหม่ลงในรายการไลบรารีที่ใช้งานได้แทนที่จะแทนที่ไลบรารีเก่า อาจทำให้แอปพลิเคชันยังคงทำงานราวกับว่ากำลังใช้ไลบรารีเก่าอยู่ ซึ่งอาจเป็นเช่นนั้นจริง ๆ
  • ไลบรารีหรือแอปพลิเคชันหลายตัวต้องการไลบรารีfoo เวอร์ชันที่แตกต่างกัน หากไลบรารีfoo เวอร์ชันต่างๆ ใช้ชื่อคลาสเดียวกัน จะไม่สามารถโหลดไลบรารีfoo เวอร์ชันเหล่านั้น โดยใช้คลาสโหลดเดอร์เดียวกันได้
  • ปัญหา JAR hell ที่ซับซ้อนที่สุดเกิดขึ้นในสถานการณ์ที่ใช้ประโยชน์จากความซับซ้อนทั้งหมดของระบบการโหลดคลาส โปรแกรม Java ไม่จำเป็นต้องใช้ตัวโหลดคลาสแบบ "แบน" เพียงตัวเดียว แต่สามารถประกอบด้วยตัวโหลดคลาสที่ซ้อนกันหลายตัว (อาจมีจำนวนมาก) ที่ทำงานร่วมกัน คลาสที่โหลดโดยตัวโหลดคลาสที่แตกต่างกันอาจโต้ตอบกันในลักษณะที่ซับซ้อนซึ่งนักพัฒนาไม่เข้าใจอย่างถ่องแท้ ทำให้เกิดข้อผิดพลาดหรือบั๊กที่วิเคราะห์ อธิบาย และแก้ไขได้ยาก[ 12 ]

OSGi Allianceได้กำหนด (เริ่มต้นจาก JSR 8 ในปี 1998) กรอบการทำงานแบบโมดูลาร์ที่มุ่งแก้ปัญหา JAR hell สำหรับ VM ในปัจจุบันและอนาคตใน ME, SE และ EE ซึ่งได้รับการยอมรับอย่างกว้างขวาง โดยใช้เมตาเดต้าในไฟล์manifest ของ JAR ไฟล์ JAR (เรียกว่า bundles) จะถูกเชื่อมต่อกันในแต่ละแพ็กเกจ Bundles สามารถส่งออกแพ็กเกจ นำเข้าแพ็กเกจ และเก็บแพ็กเกจไว้เป็นส่วนตัว ซึ่งเป็นโครงสร้างพื้นฐานของโมดูลาร์และการจัดการการพึ่งพาแบบมีเวอร์ชัน

Java 9ได้แนะนำJava Platform Module Systemในปี 2017 ซึ่งระบุรูปแบบการแจกจ่ายสำหรับชุดโค้ด Java และทรัพยากรที่เกี่ยวข้อง นอกจากนี้ยังระบุที่เก็บสำหรับจัดเก็บชุดหรือโมดูล เหล่านี้ และระบุวิธีการค้นหา โหลด และตรวจสอบความสมบูรณ์ โดยมีคุณสมบัติเช่น namespaces เพื่อแก้ไขข้อบกพร่องบางประการใน รูปแบบ JAR ที่มีอยู่ Java Platform Module System มีปรัชญาที่แตกต่างจากสถาปัตยกรรม OSGi ซึ่งมุ่งเน้นการให้ความเป็นโมดูลาร์สำหรับ Java Runtime Environment ในลักษณะที่เข้ากันได้กับเวอร์ชันก่อนหน้า โดยใช้กลไกการโหลดคลาสเริ่มต้นที่ JRE จัดให้ อย่างไรก็ตาม เนื่องจาก Java Platform Module System ไม่ได้ให้ความสามารถในการควบคุมการอยู่ร่วมกันของไลบรารีที่มีเวอร์ชันต่างกัน จึงไม่สามารถแก้ไขปัญหา JAR hell ได้อย่างสมบูรณ์[ 13 ]

ดูเพิ่มเติม

เชิงอรรถ

  1. ^ไลบรารีเหล่านี้ถูกจัดเก็บไว้ในไฟล์ Jarที่มีชื่อว่า rt.jar , core.jar , server.jarเป็นต้น
  • ชัค แม็กมานิส, " พื้นฐานของตัวโหลดคลาสใน Java ", 1996
  • Brandon E. Taylor, " การโหลดคลาส Java: พื้นฐาน(เก็บถาวรเมื่อ 2020-11-09 ที่Wayback Machine) ", 2003
  • Horstmann, เคย์ (15 เมษายน 2565) คอร์จาวา . ออราเคิลเพรสชวาไอเอสบีเอ็น 0-13-787107-4.
  • Jeff Hanson, " ควบคุมการโหลดคลาสใน Java เก็บถาวรเมื่อ 2020-12-04 ที่Wayback Machine ", 2006-06-01
  • Andreas Schaefer, " ภายในรถยกแบบคลาส ", 12 พฤศจิกายน 2003
  • Sheng Liang และ Gilad Bracha, " การโหลดคลาสแบบไดนามิกในเครื่องเสมือน Java ", ใน Proceedings of the 13th ACM Conference on Object-Oriented Programming, Systems, Languages, and Applications (OOPSLA'98), ACM SIGPLAN Notices, vol. 33, no. 10, ACM Press, 1998, หน้า 36–44 doi : 10.1145/286936.286945
  • เจเรมี วิทล็อค, " การใช้งานจริงของคลาสโหลดเดอร์แบบกำหนดเอง ", พฤษภาคม 2548
  • Christoph G. Jung, " Classloaders Revisited Hotdeploy ", Java Specialist Newsletter , 7 มิถุนายน 2001
  • ดอน ชวาร์ซ, " การจัดการการพึ่งพาของส่วนประกอบโดยใช้คลาสโหลดเดอร์ ", 13 เมษายน 2548
ดึงข้อมูลมาจาก " https://en.wikipedia.org/w/index.php?title=Java_class_loader&oldid=1342371311 "

สรุปเนื้อหา

ข้อมูลสำคัญจากบทความ

ข้อมูลสำคัญเกี่ยวกับ ตัวโหลดคลาส Java

ตัว โหลดคลาส Java ซึ่งเป็นส่วนหนึ่งของ สภาพแวดล้อมรันไทม์ Java จะ โหลด คลาส Java ลงใน เครื่องเสมือน Java แบบ ไดนามิก [ 1 ] [ 2 ] โดยปกติแล้วคลาสจะถูกโหลดเฉพาะ เมื่อมีการร้องขอ...

ตัวโหลดคลาสที่ผู้ใช้กำหนดเอง

ตัวโหลดคลาสของ Java เขียนด้วยภาษา Java ดังนั้นจึงสามารถสร้างตัวโหลดคลาสแบบกำหนดเองได้โดยไม่ต้องเข้าใจรายละเอียดปลีกย่อยของ Java Virtual Machine นอกจากตัวโหลดคลาส Bootstrap แล้ว ตัวโหลดคลาสของ Java ทุกตัวจะมีตัวโหลดคลาสแม่ [ 8 ]...

ตัวโหลดคลาสในจาการ์ตา EE

โดยทั่วไปเซิร์ฟเวอร์แอปพลิเคชัน Jakarta EE (เดิมคือ Java EE และ J2EE) จะโหลดคลาสจากไฟล์ WAR หรือ EAR ที่ถูกใช้งาน โดยใช้ตัวโหลดคลาสแบบต้นไม้ ซึ่งแยกแอปพลิเคชันออกจากแอปพลิเคชันอื่น แต่ใช้คลาสร่วมกันระหว่างโมดูลที่ถูกใช้งาน โดยทั่วไปแล้ว "...

นรก JAR

JAR hell เป็นคำที่คล้ายกับ DLL hell ซึ่งใช้เพื่ออธิบายวิธีการต่างๆ ที่กระบวนการโหลดคลาสอาจล้มเหลว [ 11 ] JAR hell สามารถเกิดขึ้นได้ 3 วิธี ได้แก่: