Istnieje wiele pytań dotyczących nielegalnego dostępu odblaskowego w Javie 9.
To, czego nie mogę znaleźć, ponieważ Google wypluwa tylko ludzi próbujących obejść komunikaty o błędach, to właśnie jest nielegalny dostęp odblaskowy.
Moje pytanie jest dość proste:
Co definiuje nielegalny dostęp odblaskowy i jakie okoliczności powodują ostrzeżenie?
Doszedłem do wniosku, że ma to coś wspólnego z zasadami hermetyzacji, które zostały wprowadzone w Javie 9, ale jak to wszystko się łączy i co powoduje ostrzeżenie, w którym scenariuszu nie mogę znaleźć wyjaśnienia.
java
java-9
java-module
Tschallacka
źródło
źródło
Odpowiedzi:
Oprócz zrozumienia dostępów między modułami i ich odpowiednich pakietów. Uważam, że sedno tego leży w systemie modułowym # Relaxed-strong-encapsulation i wybrałbym tylko odpowiednie części, aby spróbować odpowiedzieć na pytanie.
Aby ułatwić migrację do Java-9, można złagodzić silną enkapsulację modułów.
Implementacja może zapewniać dostęp statyczny , tj. Poprzez skompilowany kod bajtowy.
Może zapewnić sposób wywołania swojego systemu wykonawczego z jednym lub większą liczbą pakietów jednego lub więcej jego modułów otwartych na kod we wszystkich nienazwanych modułach , tj. Na kod w ścieżce klas. Jeśli system czasu wykonywania jest wywoływany w ten sposób i jeśli to zrobi, niektóre wywołania interfejsów API odbicia zakończą się powodzeniem tam, gdzie w przeciwnym razie zakończyłyby się niepowodzeniem.
W takich przypadkach faktycznie kończyło się na utworzeniu dostępu refleksyjnego, który jest „nielegalny”, ponieważ w czysto modularnym świecie nie miałeś takiego dostępu.
To złagodzenie enkapsulacji jest kontrolowane w czasie wykonywania przez nową opcję programu uruchamiającego,
--illegal-access
która domyślnie w Java9 jest równapermit
. Tepermit
, zapewnia trybTryby można konfigurować za pomocą wartości
debug
(komunikat, jak również śledzenie stosu dla każdego takiego dostępu),warn
(komunikat dla każdego takiego dostępu) ideny
(wyłącza takie operacje).Niewiele rzeczy do debugowania i naprawiania w aplikacjach to: -
--illegal-access=deny
aby poznać i uniknąć otwierania pakietów z jednego modułu do drugiego bez deklaracji modułu zawierającej taką dyrektywę (opens
) lub jawnego użycia--add-opens
argumentu VM.jdeps
narzędzia z--jdk-internals
opcjąPytania do takiego przykładowego ostrzeżenia: = JDK9: Wystąpiła nielegalna operacja dostępu odblaskowego. org.python.core.PySystemState
Ostatnia i ważna uwaga, próbując upewnić się, że nie napotkasz takich ostrzeżeń i będziesz bezpieczny w przyszłości, wszystko, co musisz zrobić, to upewnić się, że twoje moduły nie wykonują tych nielegalnych odblaskowych wejść. :)
źródło
Znalazłem artykuł Oracle dotyczący systemu modułów Java 9
Jak wskazano na https://stackoverflow.com/a/50251958/134894 , różnice między
AccessibleObject#setAccessible
JDK8 i JDK9 są pouczające. W szczególności dodano JDK9który podkreśla znaczenie modułów i ich eksport (w Javie 9)
źródło
–illegal-access=permit
fun
Wystarczy spojrzeć na
setAccessible()
metodę używaną do uzyskiwania dostępu doprivate
pól i metod: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-
Teraz potrzeba dużo więcej warunków, aby ta metoda działała. Jedynym powodem, dla którego nie psuje prawie całego starszego oprogramowania, jest to, że moduły generowane automatycznie ze zwykłych plików JAR są bardzo liberalne (otwieraj i eksportuj wszystko dla wszystkich).
źródło
Jeśli chcesz przejść z opcją add-open, oto polecenie, aby znaleźć moduł zapewniający który pakiet ->
java --list-modules | tr @ " " | awk '{ print $1 }' | xargs -n1 java -d
nazwa modułu będzie wyświetlana z @, a nazwy pakietów bez niego
UWAGA: testowano z JDK 11
WAŻNE: oczywiście lepiej niż dostawca pakietu nie robi nielegalnego dostępu
źródło