Правильное исправление для Java 10, жалующееся на незаконный доступ к отражению со стороны jaxb-impl 2.3.0?

#java #jaxb

#java #maven #jaxb #java-10

Вопрос:

Мы рассматриваем возможность обновления некоторого устаревшего кода до Java 10. Поскольку JAXB не отображается по умолчанию (РЕДАКТИРОВАТЬ: и правильное долгосрочное решение — не обходить симптом, используя различные флаги JVM, а исправлять его должным образом) Я добавил этот фрагмент в свой pom.xml:

     <!-- https://mvnrepository.com/artifact/javax.xml.bind/jaxb-api -->
    <dependency>
        <groupId>javax.xml.bind</groupId>
        <artifactId>jaxb-api</artifactId>
        <version>2.3.0</version>
    </dependency>
    <dependency>
        <groupId>com.sun.xml.bind</groupId>
        <artifactId>jaxb-core</artifactId>
        <version>2.3.0</version>
    </dependency>
    <dependency>
        <groupId>com.sun.xml.bind</groupId>
        <artifactId>jaxb-impl</artifactId>
        <version>2.3.0</version>
    </dependency>
  

К сожалению, при запуске stderr все еще выводится предупреждение. По-видимому, это неправильное исправление.

 WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.sun.xml.bind.v2.runtime.reflect.opt.Injector (file:/home/tra/.m2/repository/com/sun/xml/bind/jaxb-impl/2.3.0/jaxb-impl-2.3.0.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int)
WARNING: Please consider reporting this to the maintainers of com.sun.xml.bind.v2.runtime.reflect.opt.Injector
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
  

Полный вывод из --illegal-access=debug :

 WARNING: Illegal reflective access by com.sun.xml.bind.v2.runtime.reflect.opt.Injector (file:/home/tra/.m2/repository/com/sun/xml/bind/jaxb-impl/2.3.0/jaxb-impl-2.3.0.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int)
    at com.sun.xml.bind.v2.runtime.reflect.opt.Injector.getMethod(Injector.java:222)
    at com.sun.xml.bind.v2.runtime.reflect.opt.Injector.access$000(Injector.java:74)
    at com.sun.xml.bind.v2.runtime.reflect.opt.Injector$1.run(Injector.java:175)
    at com.sun.xml.bind.v2.runtime.reflect.opt.Injector$1.run(Injector.java:172)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at com.sun.xml.bind.v2.runtime.reflect.opt.Injector.<clinit>(Injector.java:171)
    at com.sun.xml.bind.v2.runtime.reflect.opt.AccessorInjector.prepare(AccessorInjector.java:81)
    at com.sun.xml.bind.v2.runtime.reflect.opt.OptimizedAccessorFactory.get(OptimizedAccessorFactory.java:179)
    at com.sun.xml.bind.v2.runtime.reflect.Accessor$FieldReflection.optimize(Accessor.java:285)
    at com.sun.xml.bind.v2.runtime.property.ArrayProperty.<init>(ArrayProperty.java:68)
    at com.sun.xml.bind.v2.runtime.property.ArrayERProperty.<init>(ArrayERProperty.java:88)
    at com.sun.xml.bind.v2.runtime.property.ArrayElementProperty.<init>(ArrayElementProperty.java:100)
    at com.sun.xml.bind.v2.runtime.property.ArrayElementNodeProperty.<init>(ArrayElementNodeProperty.java:62)
    at com.sun.xml.bind.v2.runtime.property.PropertyFactory.create(PropertyFactory.java:128)
    at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.<init>(ClassBeanInfoImpl.java:181)
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:514)
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:331)
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:139)
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1156)
    at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:165)
    at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:297)
    at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:286)
    at javax.xml.bind.ContextFinder.find(ContextFinder.java:409)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:721)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:662)
    at dk.statsbiblioteket.medieplatform.autonomous.PremisManipulatorFactory.<init>(PremisManipulatorFactory.java:28)
    at dk.statsbiblioteket.digital_pligtaflevering_aviser.tools.modules.DomsModule.providePremisManipulatorFactory(DomsModule.java:182)
    at dk.statsbiblioteket.digital_pligtaflevering_aviser.tools.modules.DomsModule_ProvidePremisManipulatorFactoryFactory.get(DomsModule_ProvidePremisManipulatorFactoryFactory.java:32)
    at dk.statsbiblioteket.digital_pligtaflevering_aviser.tools.modules.DomsModule_ProvidePremisManipulatorFactoryFactory.get(DomsModule_ProvidePremisManipulatorFactoryFactory.java:11)
    at dk.statsbiblioteket.digital_pligtaflevering_aviser.tools.modules.DomsModule_ProvideSBOIEventIndexFactory.get(DomsModule_ProvideSBOIEventIndexFactory.java:56)
    at dk.statsbiblioteket.digital_pligtaflevering_aviser.tools.modules.DomsModule_ProvideSBOIEventIndexFactory.get(DomsModule_ProvideSBOIEventIndexFactory.java:12)
    at dk.statsbiblioteket.digital_pligtaflevering_aviser.doms.DomsRepository_Factory.get(DomsRepository_Factory.java:53)
WARNING: Illegal reflective access by com.sun.xml.bind.v2.runtime.reflect.opt.Injector (file:/home/tra/.m2/repository/com/sun/xml/bind/jaxb-impl/2.3.0/jaxb-impl-2.3.0.jar) to method java.lang.ClassLoader.resolveClass(java.lang.Class)
    at com.sun.xml.bind.v2.runtime.reflect.opt.Injector.getMethod(Injector.java:222)
    at com.sun.xml.bind.v2.runtime.reflect.opt.Injector.access$000(Injector.java:74)
    at com.sun.xml.bind.v2.runtime.reflect.opt.Injector$1.run(Injector.java:175)
    at com.sun.xml.bind.v2.runtime.reflect.opt.Injector$1.run(Injector.java:172)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at com.sun.xml.bind.v2.runtime.reflect.opt.Injector.<clinit>(Injector.java:171)
    at com.sun.xml.bind.v2.runtime.reflect.opt.AccessorInjector.prepare(AccessorInjector.java:81)
    at com.sun.xml.bind.v2.runtime.reflect.opt.OptimizedAccessorFactory.get(OptimizedAccessorFactory.java:179)
    at com.sun.xml.bind.v2.runtime.reflect.Accessor$FieldReflection.optimize(Accessor.java:285)
    at com.sun.xml.bind.v2.runtime.property.ArrayProperty.<init>(ArrayProperty.java:68)
    at com.sun.xml.bind.v2.runtime.property.ArrayERProperty.<init>(ArrayERProperty.java:88)
    at com.sun.xml.bind.v2.runtime.property.ArrayElementProperty.<init>(ArrayElementProperty.java:100)
    at com.sun.xml.bind.v2.runtime.property.ArrayElementNodeProperty.<init>(ArrayElementNodeProperty.java:62)
    at com.sun.xml.bind.v2.runtime.property.PropertyFactory.create(PropertyFactory.java:128)
    at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.<init>(ClassBeanInfoImpl.java:181)
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:514)
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:331)
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:139)
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1156)
    at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:165)
    at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:297)
    at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:286)
    at javax.xml.bind.ContextFinder.find(ContextFinder.java:409)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:721)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:662)
    at dk.statsbiblioteket.medieplatform.autonomous.PremisManipulatorFactory.<init>(PremisManipulatorFactory.java:28)
    at dk.statsbiblioteket.digital_pligtaflevering_aviser.tools.modules.DomsModule.providePremisManipulatorFactory(DomsModule.java:182)
    at dk.statsbiblioteket.digital_pligtaflevering_aviser.tools.modules.DomsModule_ProvidePremisManipulatorFactoryFactory.get(DomsModule_ProvidePremisManipulatorFactoryFactory.java:32)
    at dk.statsbiblioteket.digital_pligtaflevering_aviser.tools.modules.DomsModule_ProvidePremisManipulatorFactoryFactory.get(DomsModule_ProvidePremisManipulatorFactoryFactory.java:11)
    at dk.statsbiblioteket.digital_pligtaflevering_aviser.tools.modules.DomsModule_ProvideSBOIEventIndexFactory.get(DomsModule_ProvideSBOIEventIndexFactory.java:56)
    at dk.statsbiblioteket.digital_pligtaflevering_aviser.tools.modules.DomsModule_ProvideSBOIEventIndexFactory.get(DomsModule_ProvideSBOIEventIndexFactory.java:12)
    at dk.statsbiblioteket.digital_pligtaflevering_aviser.doms.DomsRepository_Factory.get(DomsRepository_Factory.java:53)
WARNING: Illegal reflective access by com.sun.xml.bind.v2.runtime.reflect.opt.Injector (file:/home/tra/.m2/repository/com/sun/xml/bind/jaxb-impl/2.3.0/jaxb-impl-2.3.0.jar) to method java.lang.ClassLoader.findLoadedClass(java.lang.String)
    at com.sun.xml.bind.v2.runtime.reflect.opt.Injector.getMethod(Injector.java:222)
    at com.sun.xml.bind.v2.runtime.reflect.opt.Injector.access$000(Injector.java:74)
    at com.sun.xml.bind.v2.runtime.reflect.opt.Injector$1.run(Injector.java:175)
    at com.sun.xml.bind.v2.runtime.reflect.opt.Injector$1.run(Injector.java:172)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at com.sun.xml.bind.v2.runtime.reflect.opt.Injector.<clinit>(Injector.java:171)
    at com.sun.xml.bind.v2.runtime.reflect.opt.AccessorInjector.prepare(AccessorInjector.java:81)
    at com.sun.xml.bind.v2.runtime.reflect.opt.OptimizedAccessorFactory.get(OptimizedAccessorFactory.java:179)
    at com.sun.xml.bind.v2.runtime.reflect.Accessor$FieldReflection.optimize(Accessor.java:285)
    at com.sun.xml.bind.v2.runtime.property.ArrayProperty.<init>(ArrayProperty.java:68)
    at com.sun.xml.bind.v2.runtime.property.ArrayERProperty.<init>(ArrayERProperty.java:88)
    at com.sun.xml.bind.v2.runtime.property.ArrayElementProperty.<init>(ArrayElementProperty.java:100)
    at com.sun.xml.bind.v2.runtime.property.ArrayElementNodeProperty.<init>(ArrayElementNodeProperty.java:62)
    at com.sun.xml.bind.v2.runtime.property.PropertyFactory.create(PropertyFactory.java:128)
    at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.<init>(ClassBeanInfoImpl.java:181)
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:514)
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:331)
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:139)
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1156)
    at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:165)
    at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:297)
    at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:286)
    at javax.xml.bind.ContextFinder.find(ContextFinder.java:409)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:721)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:662)
    at dk.statsbiblioteket.medieplatform.autonomous.PremisManipulatorFactory.<init>(PremisManipulatorFactory.java:28)
    at dk.statsbiblioteket.digital_pligtaflevering_aviser.tools.modules.DomsModule.providePremisManipulatorFactory(DomsModule.java:182)
    at dk.statsbiblioteket.digital_pligtaflevering_aviser.tools.modules.DomsModule_ProvidePremisManipulatorFactoryFactory.get(DomsModule_ProvidePremisManipulatorFactoryFactory.java:32)
    at dk.statsbiblioteket.digital_pligtaflevering_aviser.tools.modules.DomsModule_ProvidePremisManipulatorFactoryFactory.get(DomsModule_ProvidePremisManipulatorFactoryFactory.java:11)
    at dk.statsbiblioteket.digital_pligtaflevering_aviser.tools.modules.DomsModule_ProvideSBOIEventIndexFactory.get(DomsModule_ProvideSBOIEventIndexFactory.java:56)
    at dk.statsbiblioteket.digital_pligtaflevering_aviser.tools.modules.DomsModule_ProvideSBOIEventIndexFactory.get(DomsModule_ProvideSBOIEventIndexFactory.java:12)
    at dk.statsbiblioteket.digital_pligtaflevering_aviser.doms.DomsRepository_Factory.get(DomsRepository_Factory.java:53)
  

Какие правильные зависимости следует использовать здесь для решения этой проблемы?

Комментарии:

1. Можете ли вы запустить свое приложение --illegal-access=debug и обновить вопрос?

2. Я бы рекомендовал сообщить об этом владельцам JAXB. Похоже, ошибка уже зарегистрирована и отслеживается в #javaee/jaxb-v2/issues/ 1197 . Кроме того, в то же время, эта статья может быть полезна разработчикам для изучения MethoHandles.LookUp реализации в качестве альтернативы использованию Unsafe.defineClass

3. Ошибке @nullpointer всего три дня, поэтому ее не существовало, когда я исследовал это изначально. Я надеюсь, что это побудит сопровождающих JAXB создать правильное исправление.

4. @ZhekaKozlov добавил запрошенный вывод.

5. Поскольку эта проблема, вероятно, существует с Java 9, я думаю, разработчики JAXB должны знать об этом. Таким образом, долгосрочное решение — дождаться исправленной версии, но в то же время вы можете просто жить с сообщенным доступом. Это именно то, что стоит за этим, чтобы разработчики знали о проблеме, все еще выполняя код с текущей версией.

Ответ №1:

среда выполнения jaxb-ri использует ClassLoader#defineClass / Unsafe#defineClass некоторую модификацию байт-кода во время выполнения для оптимизации производительности. ClassLoader#defineClass сначала выполняется попытка, которая вызывает предупреждение.

Эта устаревшая оптимизация полностью удалена в jaxb-ri master (после 2.3.0, еще не выпущена).

Чтобы отключить эту оптимизацию для 2.3.0, установите системное свойство com.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize .

После следующего выпуска jaxb-ri обновление до последней версии удалит предупреждение. артефакт jaxb-core будет прекращен в пользу поддержки JPMS. Правильный pom будет выглядеть так:

 <dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.4.0</version> 
</dependency>
<dependency>
    <groupId>org.glassfish.jaxb</groupId>
    <artifactId>jaxb-runtime</artifactId>
    <version>2.4.0</version> 
</dependency>
  

Если вы хотите попробовать раньше, вы можете выбрать последнюю продвигаемую сборку из:
https://maven.java.net/content/groups/promoted/org/glassfish/jaxb/jaxb-runtime /

Комментарии:

1. ДА. Не забудьте удалить jaxb-core из зависимостей, этот артефакт будет прекращен из-за проблемы с разделением пакета JPMS.

2. Теперь выпущена версия 2.3.1, которая исправляет предупреждение о «незаконном отражающем доступе» для меня на java 11. 2.4.0 все еще не выпущен официально, поэтому 2.3.1 кажется мне лучшим выбором.

3. @Evan Насколько я понимаю, b предназначен для сборки, а не для бета-версии.

4. Почему предупреждение возвращается с версией 3.0.0?

5. в версии 3.0.0 я должен: System.setProperty(«org.glassfish.jaxb.runtime.v2.байт-код. classstailor.noOptimize», «true»);

Ответ №2:

слава @Roman Grigoriadi, он был прав, обновленная 2.4 версия исправляет проблемы с предупреждениями.

Просто добавьте приведенные ниже зависимости в pom файл

 <dependency>
  <groupId>javax.xml.bind</groupId>
  <artifactId>jaxb-api</artifactId>
  <version>2.4.0-b180830.0359</version>
</dependency>
<dependency>
  <groupId>org.glassfish.jaxb</groupId>
  <artifactId>jaxb-runtime</artifactId>
  <version>2.4.0-b180608.0325</version>
</dependency>
  

Ответ №3:

Я только что потратил полдня на просмотр старых блогов и сообщений на эту тему, наиболее устаревших и не работающих. Или работает только с предупреждениями во время выполнения. По состоянию на декабрь 2020 года следующее работает с Java 15 без каких-либо ошибок или предупреждений:

 <dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.3.1</version>
</dependency>
<dependency>
    <groupId>org.glassfish.jaxb</groupId>
    <artifactId>jaxb-runtime</artifactId>
    <version>2.3.2</version>
</dependency>
  

Ответ №4:

Чтобы заставить JAXB 2.3.3 работать с JDK 16 (т.Е. Работать с JDK 1.8 — 17 EA): ВСЕГДА добавляйте ‘Multi-Release: true’ в свой MANIFEST.MF!

смотрите мои комментарии:

https://github.com/eclipse-ee4j/jaxb-ri/issues/1197#issuecomment-810908755

Вот мои конкретные зависимости maven (явные) для использования JAXB 2.3.3 в моем проекте:

 <!-- JAXB 2.3.3 (jdk 8 ) -->
    <dependency>
        <groupId>jakarta.xml.bind</groupId>
        <artifactId>jakarta.xml.bind-api</artifactId>
        <version>2.3.3</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jaxb</groupId>
        <artifactId>jaxb-runtime</artifactId>
        <version>2.3.3</version>
    </dependency>

    <!-- JAXB dependencies -->
    <dependency>
        <groupId>jakarta.activation</groupId>
        <artifactId>jakarta.activation-api</artifactId>
        <version>1.2.2</version>
    </dependency>
    <dependency>
        <groupId>com.sun.activation</groupId>
        <artifactId>jakarta.activation</artifactId>
        <version>1.2.2</version>
    </dependency>

    <dependency>
        <groupId>com.sun.istack</groupId>
        <artifactId>istack-commons-runtime</artifactId>
        <version>3.0.11</version>
    </dependency>
    <dependency>
        <groupId>com.sun.xml.fastinfoset</groupId>
        <artifactId>FastInfoset</artifactId>
        <version>1.2.18</version>
    </dependency>
    <dependency>
        <groupId>org.jvnet.staxex</groupId>
        <artifactId>stax-ex</artifactId>
        <version>1.8.3</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jaxb</groupId>
        <artifactId>txw2</artifactId>
        <version>2.3.3</version>
    </dependency>
  

Комментарии:

1. Обратите внимание, что это связано с тем, что вы создаете один jar из всех ваших зависимостей. Затем вам нужно включить все поля из их МАНИФЕСТА. MF в вашем новом самодельном глобальном MANIFEST.MF. Если вы не переупаковываете, в этом не должно быть необходимости.