Не работает ли модульная система Java для синтетических полей?
Я тестирую некоторые библиотеки генерации байт-кода с системой модулей java. Я скомпилировал java 11 со следующими изменениями в java.base module-info.java:
module java.base {
...
exports java.lang.reflect to <some java and custom modules>;
...
}
Затем я запускаю java с параметром «--illegal-access=deny». Когда я использую эту скомпилированную версию Java с библиотекой javassist, она генерирует следующий класс в безымянном модуле:
public class SomeJavassistProxy extends SomeClass implements WriteReplaceInterface, ProxyObject {
private MethodHandler handler;
private static Method[] _methods_;
...
Java выдает какой-то «класс java.lang.IllegalAccessError». модуль".
Это ожидаемое поведение.
Затем я попробовал библиотеку bytebuddy, и она сгенерировала следующий класс:
public class SomeClass$HibernateProxy$7DKVefUe extends SomeClass implements HibernateProxy, ProxyConfiguration {
private Interceptor $$_hibernate_interceptor;
// $FF: synthetic field
private static final Method cachedValue$ghVgnbHc$4cscpe1 = Object.class.getMethod("toString");
// $FF: synthetic field
private static final Method cachedValue$ghVgnbHc$o23rrk2 = HibernateProxy.class.getMethod("getHibernateLazyInitializer");
...
Этот класс также генерируется в безымянном модуле. Но на этот раз все работает и никаких ошибок не выдает. Каким-то образом он может получить доступ к java.lang.reflect, несмотря на то, что пакет не должен быть доступен для безымянного модуля.
Единственное отличие, которое я вижу, это синтетическое поле с java.lang.reflect.Method в сгенерированном bytebuddy классе.
Итак, мой вопрос: не работает ли система модулей Java с синтетическими полями?
1 ответ
Извини, я виноват.
Оказывается, IllegalAccessError возникает только тогда, когда вы фактически вызываете методы из защищенного пакета (в моем случае java.lang.reflect) внутри модуля, который не может получить доступ к этому пакету (в моем случае безымянный модуль).
Если есть только ссылка на защищенный пакет, исключение не генерируется.
В примере с bytebuddy есть только ссылка на класс Method в безымянном модуле. Эта ссылка передается классу Interceptor (в моем случае он принадлежит автоматическому модулю, который имеет доступ к java.lang.reflect), где происходит фактический вызов метода.
Таким образом, это не имеет ничего общего с синтетическими полями.