Не работает ли модульная система 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), где происходит фактический вызов метода.

Таким образом, это не имеет ничего общего с синтетическими полями.