นอกเหนือจากความเข้าใจในการเข้าถึงระหว่างโมดูลและแพ็คเกจตามลำดับ ฉันเชื่อว่าจุดสำคัญของมันอยู่ที่Module System # Relaxed-strong-encapsulationและฉันจะเลือกส่วนที่เกี่ยวข้องกับเชอร์รี่เพื่อลองตอบคำถาม
อะไรกำหนดการเข้าถึงแบบสะท้อนแสงที่ผิดกฎหมายและสถานการณ์ใดที่ทำให้เกิดคำเตือน
เพื่อช่วยในการโอนย้ายไปยัง Java-9 การห่อหุ้มโมดูลที่แน่นหนาสามารถผ่อนคลายได้
การใช้งานอาจให้การเข้าถึงแบบคงที่กล่าวคือโดย bytecode ที่คอมไพล์
อาจจัดเตรียมวิธีการเรียกใช้ระบบรันไทม์โดยมีแพ็กเกจอย่างน้อยหนึ่งแพ็กเกจของโมดูลอย่างน้อยหนึ่งโมดูลที่เปิดขึ้นเพื่อโค้ดในโมดูลที่ไม่มีชื่อทั้งหมดนั่นคือเพื่อโค้ดบนคลาสพา ธ หากมีการเรียกใช้ระบบรันไทม์ด้วยวิธีนี้และหากทำเช่นนั้นการเรียกใช้ API การสะท้อนบางอย่างจะประสบความสำเร็จมิฉะนั้นจะล้มเหลว
ในกรณีเช่นนี้คุณลงเอยด้วยการเข้าถึงแบบสะท้อนแสงซึ่ง"ผิดกฎหมาย"เนื่องจากในโลกโมดูลาร์ที่บริสุทธิ์คุณไม่ได้ตั้งใจที่จะเข้าถึงเช่นนั้น
มันรวมตัวกันอย่างไรและอะไรทำให้เกิดคำเตือนในสถานการณ์ใด
การผ่อนคลายของการห่อหุ้มนี้มีการควบคุมที่รันไทม์โดยเป็นตัวเลือกที่ปล่อยใหม่--illegal-access
ซึ่งเริ่มต้นโดยใน Java9 permit
เท่ากับ permit
โหมดเพื่อให้แน่ใจ
การดำเนินการเข้าถึงแบบสะท้อนแสงครั้งแรกไปยังแพ็คเกจดังกล่าวทำให้ต้องออกคำเตือน แต่จะไม่มีการออกคำเตือนหลังจากจุดนั้น คำเตือนเดียวนี้อธิบายถึงวิธีการเปิดใช้งานคำเตือนเพิ่มเติม ไม่สามารถระงับคำเตือนนี้ได้
โหมดต่างๆสามารถกำหนดค่าได้ด้วยค่าdebug
(ข้อความเช่นเดียวกับ stacktrace สำหรับทุกการเข้าถึงดังกล่าว) warn
(ข้อความสำหรับแต่ละการเข้าถึงดังกล่าว) และdeny
(ปิดใช้งานการดำเนินการดังกล่าว)
มีบางสิ่งที่ควรแก้ไขข้อบกพร่องและแก้ไขแอปพลิเคชัน ได้แก่ : -
- เรียกใช้ด้วย
--illegal-access=deny
เพื่อทำความรู้จักและหลีกเลี่ยงการเปิดแพ็กเกจ ing จากโมดูลหนึ่งไปยังอีกโมดูลหนึ่งโดยไม่มีการประกาศโมดูลรวมถึง directive ( opens
) หรือการใช้--add-opens
VM arg อย่างชัดเจน
- การอ้างอิงแบบคงที่จากโค้ดที่คอมไพล์ไปยัง JDK-internal APIs สามารถระบุได้โดยใช้
jdeps
เครื่องมือพร้อม--jdk-internals
ตัวเลือก
ข้อความเตือนที่ออกเมื่อตรวจพบการดำเนินการสะท้อนแสงที่ผิดกฎหมายมีรูปแบบต่อไปนี้:
WARNING: Illegal reflective access by $PERPETRATOR to $VICTIM
ที่อยู่:
$PERPETRATOR
คือชื่อที่มีคุณสมบัติครบถ้วนของประเภทที่มีรหัสที่เรียกใช้การดำเนินการสะท้อนแสงที่เป็นปัญหาบวกกับแหล่งรหัส (เช่นเส้นทางไฟล์ JAR) ถ้ามีและ
$VICTIM
เป็นสตริงที่อธิบายถึงสมาชิกที่ถูกเข้าถึงรวมถึงชื่อแบบเต็มของชนิดการปิดล้อม
คำถามสำหรับคำเตือนตัวอย่างดังกล่าว: = JDK9: เกิดการดำเนินการเข้าถึงแบบสะท้อนแสงที่ผิดกฎหมาย org.python.core.PySystemState
หมายเหตุสุดท้ายและสำคัญในขณะที่พยายามทำให้แน่ใจว่าคุณจะไม่เผชิญกับคำเตือนดังกล่าวและปลอดภัยในอนาคตสิ่งที่คุณต้องทำคือตรวจสอบให้แน่ใจว่าโมดูลของคุณไม่ได้ทำการเข้าถึงแบบสะท้อนแสงที่ผิดกฎหมาย :)