Ada banyak pertanyaan seputar akses reflektif ilegal di Java 9.
Sekarang apa yang tidak dapat saya temukan karena semua yang dimuntahkan Google adalah orang-orang yang mencoba mengatasi pesan kesalahan, adalah apa sebenarnya akses reflektif ilegal itu.
Jadi pertanyaan saya cukup sederhana adalah:
Apa yang mendefinisikan akses reflektif ilegal dan keadaan apa yang memicu peringatan?
Saya telah mengumpulkan bahwa itu ada hubungannya dengan prinsip-prinsip enkapsulasi yang diperkenalkan di Java 9, tetapi bagaimana semuanya hang bersama dan apa yang memicu peringatan dalam skenario apa yang tidak dapat saya temukan penjelasannya.
java
java-9
java-module
Tschallacka
sumber
sumber
Jawaban:
Terlepas dari pemahaman tentang akses antar modul dan paketnya masing-masing. Saya percaya inti dari itu terletak pada Sistem Modul # Santai-kuat-enkapsulasi dan saya hanya akan memilih bagian yang relevan untuk mencoba dan menjawab pertanyaan itu.
Untuk membantu migrasi ke Java-9, enkapsulasi yang kuat dari modul dapat dilonggarkan.
Implementasi dapat menyediakan akses statis , yaitu bytecode yang dikompilasi.
Dapat menyediakan sarana untuk menjalankan sistem waktu berjalannya dengan satu atau lebih paket dari satu atau lebih modulnya yang terbuka untuk kode di semua modul yang tidak disebutkan namanya , yaitu ke kode pada jalur kelas. Jika sistem run-time dipanggil dengan cara ini, dan jika dengan melakukan itu beberapa pemanggilan API refleksi berhasil, jika tidak maka akan gagal.
Dalam kasus seperti itu, Anda sebenarnya akhirnya membuat akses reflektif yang "ilegal" karena dalam dunia modular murni Anda tidak dimaksudkan untuk melakukan akses tersebut.
Pelonggaran enkapsulasi ini dikontrol pada waktu proses oleh opsi peluncur baru
--illegal-access
yang sama dengan default di Java9permit
. Thepermit
modus MemastikanMode dapat dikonfigurasi dengan nilai
debug
(pesan serta pelacakan tumpukan untuk setiap akses tersebut),warn
(pesan untuk setiap akses tersebut), dandeny
(menonaktifkan operasi tersebut).Beberapa hal untuk di-debug dan diperbaiki pada aplikasi adalah: -
--illegal-access=deny
untuk mengetahui tentang dan menghindari membuka paket dari satu modul ke modul lain tanpa deklarasi modul termasuk direktif (opens
) atau penggunaan eksplisit--add-opens
argumen VM.jdeps
alat dengan--jdk-internals
opsi tersebutPertanyaan untuk contoh peringatan seperti itu: = JDK9: Operasi akses reflektif ilegal telah terjadi. org.python.core.PySystemState
Terakhir dan catatan penting, saat mencoba memastikan bahwa Anda tidak menghadapi peringatan seperti itu dan aman di masa depan, yang perlu Anda lakukan adalah memastikan modul Anda tidak membuat akses reflektif ilegal tersebut. :)
sumber
Ada artikel Oracle yang saya temukan tentang sistem modul Java 9
Seperti yang ditunjukkan di https://stackoverflow.com/a/50251958/134894 , perbedaan antara
AccessibleObject#setAccessible
untuk JDK8 dan JDK9 bersifat instruktif. Secara khusus, JDK9 menambahkanyang menyoroti pentingnya modul dan ekspornya (di Java 9)
sumber
–illegal-access=permit
...fun
Lihat saja
setAccessible()
metode yang digunakan untuk mengaksesprivate
bidang dan metode:https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/AccessibleObject.html#setAccessible-boolean-
https://docs.oracle.com/javase/9/docs/api/java/lang/reflect/AccessibleObject.html#setAccessible-boolean-
Sekarang ada lebih banyak kondisi yang diperlukan agar metode ini berfungsi. Satu-satunya alasan mengapa ia tidak merusak hampir semua perangkat lunak lama adalah bahwa modul yang dibuat secara otomatis dari JAR biasa sangat permisif (buka dan ekspor semuanya untuk semua orang).
sumber
Jika Anda ingin menggunakan opsi add-open, berikut adalah perintah untuk menemukan modul mana yang menyediakan paket mana ->
java --list-modules | tr @ " " | awk '{ print $1 }' | xargs -n1 java -d
nama modul akan ditampilkan dengan @ sedangkan nama paket tanpa itu
CATATAN: diuji dengan JDK 11
PENTING: jelas lebih baik daripada penyedia paket tidak melakukan akses ilegal
sumber