Почему мой безопасный код не работает после перехода на JDK 17

Мы создаем REST API с помощью тестов. API работает отлично, и у нас нет никаких проблем с ним. Ошибки, которые мы получаем, находятся в тестовой части.

В тестах используется библиотека Rest Assured. Мы должны использовать JDK 17 в качестве выбора уровня организации.

Мы столкнулись с проблемой при выполнении наших тестов REST Assured после обновления до JDK 17. Возможно, это как-то связано с тем, что отражение не разрешено в JDK 17.

Мы получаем java.lang.ExceptionInInitializerError для следующих строк кода

    RestAssured.baseURI = Constants.BASE_URI;

    RestAssured.port = Constants.PORT;

    RestAssured.basePath = Constants.BASE_PATH;

Есть ли у вас какие-либо советы/решения/обходные пути. Мы не можем использовать другую версию Java, поскольку это выбор на уровне организации.

Мы устанавливаем baseURI, порт и basePath для всех тестов, используя приведенный выше код. Раньше это работало, но после того, как мы перешли на JDK 17, похоже, возникла проблема.

java.lang.ExceptionInInitializerError
    at io.restassured.builder.RequestSpecBuilder.<init>(RequestSpecBuilder.java:79)
    at com.teamcenter.services.strong.utils.TestBase.createRequestSpecification(TestBase.java:99)
    at com.teamcenter.services.strong.utils.TestBase.createRequestSpecification(TestBase.java:82)
    at com.teamcenter.services.strong.utils.TestBase.setUp(TestBase.java:116)
    at com.teamcenter.services.strong.IncludeRuleTest.setUp(IncludeRuleTest.java:36)
    at junit.framework.TestCase.runBare(TestCase.java:140)
    at junit.framework.TestResult$1.protect(TestResult.java:122)
    at junit.framework.TestResult.runProtected(TestResult.java:142)
    at junit.framework.TestResult.run(TestResult.java:125)
    at junit.framework.TestCase.run(TestCase.java:130)
    at junit.framework.TestSuite.runTest(TestSuite.java:241)
    at junit.framework.TestSuite.run(TestSuite.java:236)
    at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:90)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:93)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:40)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:529)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:756)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:452)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make java.lang.String(char[],int,int,java.lang.Void) accessible: module java.base does not "opens java.lang" to unnamed module @3cda1055
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
    at java.base/java.lang.reflect.Constructor.checkCanSetAccessible(Constructor.java:188)
    at java.base/java.lang.reflect.Constructor.setAccessible(Constructor.java:181)
    at org.codehaus.groovy.reflection.CachedConstructor$1.run(CachedConstructor.java:44)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:318)
    at org.codehaus.groovy.reflection.CachedConstructor.<init>(CachedConstructor.java:42)
    at org.codehaus.groovy.reflection.CachedClass$2.initValue(CachedClass.java:79)
    at org.codehaus.groovy.reflection.CachedClass$2.initValue(CachedClass.java:69)
    at org.codehaus.groovy.util.LazyReference.getLocked(LazyReference.java:49)
    at org.codehaus.groovy.util.LazyReference.get(LazyReference.java:36)
    at org.codehaus.groovy.reflection.CachedClass.getConstructors(CachedClass.java:268)
    at groovy.lang.MetaClassImpl.<init>(MetaClassImpl.java:218)
    at groovy.lang.MetaClassImpl.<init>(MetaClassImpl.java:228)
    at groovy.lang.MetaClassRegistry$MetaClassCreationHandle.createNormalMetaClass(MetaClassRegistry.java:171)
    at groovy.lang.MetaClassRegistry$MetaClassCreationHandle.createWithCustomLookup(MetaClassRegistry.java:161)
    at groovy.lang.MetaClassRegistry$MetaClassCreationHandle.create(MetaClassRegistry.java:144)
    at org.codehaus.groovy.reflection.ClassInfo.getMetaClassUnderLock(ClassInfo.java:253)
    at org.codehaus.groovy.reflection.ClassInfo.getMetaClass(ClassInfo.java:285)
    at org.codehaus.groovy.reflection.ClassInfo.getMetaClass(ClassInfo.java:295)
    at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.getMetaClass(MetaClassRegistryImpl.java:261)
    at org.codehaus.groovy.runtime.InvokerHelper.getMetaClass(InvokerHelper.java:873)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.createPojoSite(CallSiteArray.java:125)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.createCallSite(CallSiteArray.java:166)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
    at io.restassured.internal.RequestSpecificationImpl.<clinit>(RequestSpecificationImpl.groovy:86)
    ... 19 more

Я люблю гадать.

Elliott Frisch 17.02.2023 05:35

Некоторое объяснение ошибки см. в разделе Как решить InaccessibleObjectException («Невозможно сделать {member} доступным: модуль {A} не «открывает {package}» для {B}») в Java 9?.

Slaw 17.02.2023 05:36

@ElliottFrisch Это говорит о разделенных пакетах. Ошибка OP не связана с разделенными пакетами. Или я что-то упускаю?

Slaw 17.02.2023 05:48

@Slaw Мы понятия не имеем, как OP упаковывает свой код или даже какую версию проверенного OP использует; отсюда и догадки. Но модуль java.base не «открывает java.lang» для безымянного модуля, подразумевающего модули. Модули Java 9+. И эта заметка помечена как «java 9+».

Elliott Frisch 17.02.2023 06:00
Как сделать движок для футбольного матча? (простой вариант)
Как сделать движок для футбольного матча? (простой вариант)
Футбол. Для многих людей, живущих на земле, эта игра - больше, чем просто спорт. И эти люди всегда мечтают стать футболистом или менеджером. Но, к...
Знайте свои исключения!
Знайте свои исключения!
В Java исключение - это событие, возникающее во время выполнения программы, которое нарушает нормальный ход выполнения инструкций программы. Когда...
Лучшая компания по разработке спортивных приложений
Лучшая компания по разработке спортивных приложений
Ищете лучшую компанию по разработке спортивных приложений? Этот список, несомненно, облегчит вашу работу!
Blibli Automation Journey - Как захватить сетевой трафик с помощью утилиты HAR в Selenium 4
Blibli Automation Journey - Как захватить сетевой трафик с помощью утилиты HAR в Selenium 4
Если вы являетесь веб-разработчиком или тестировщиком, вы можете быть знакомы с Selenium, популярным инструментом для автоматизации работы...
Фото ️🔁 Radek Jedynak 🔃 on ️🔁 Unsplash 🔃
Фото ️🔁 Radek Jedynak 🔃 on ️🔁 Unsplash 🔃
Что такое Java 8 Streams API? Java 8 Stream API
Деревья поиска (Алгоритм4 Заметки к учебнику)
Деревья поиска (Алгоритм4 Заметки к учебнику)
(1) Двоичные деревья поиска: среднее lgN, наихудшее N для вставки и поиска.
0
4
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это фундаментальная проблема Groovy.

Groovy — это динамический язык, использующий Reflection для доступа к элементам и вызывающий setAccessible(true) для всех из них.

Это не должно было работать таким образом, но было реализовано таким образом, чтобы исправить доступ из закрытий к закрытым членам с побочным ущербом от игнорирования private везде. Видеть

  • Приватный метод в groovy не является приватным

  • Классный вызов приватного метода в суперклассе Java

Конструктор String(char[],int,int,java.lang.Void) даже не существует в более старых версиях Java, поэтому это не тот случай, когда старая программа полагается на него, а вместо этого среда выполнения Groovy пытается кэшировать все члены класса и вызывает setAccessible(true) заранее, как мы можем вывести из трассировки стека

    at org.codehaus.groovy.reflection.CachedClass.getConstructors(CachedClass.java:268)
    at groovy.lang.MetaClassImpl.<init>(MetaClassImpl.java:218)
    at groovy.lang.MetaClassImpl.<init>(MetaClassImpl.java:228)
    at groovy.lang.MetaClassRegistry$MetaClassCreationHandle.createNormalMetaClass(MetaClassRegistry.java:171)
    at groovy.lang.MetaClassRegistry$MetaClassCreationHandle.createWithCustomLookup(MetaClassRegistry.java:161)
    at groovy.lang.MetaClassRegistry$MetaClassCreationHandle.create(MetaClassRegistry.java:144)

Обратите внимание на часть имени MetaClass, предлагающую обработку для каждого класса, и множественное число в имени метода getConstructors, предполагающее, что он пытается получить все конструкторы.

Поскольку вы даже не пытаетесь получить доступ к члену класса String в опубликованном коде, кажется, что уже достаточно использовать/сослаться на тип, чтобы вызвать инициализацию метаинформации.


Для обычного программного обеспечения Java мы бы предложили определить места, где программное обеспечение обращается к внутренним компонентам, а затем включить конкретную опцию --add-opens в качестве временного обходного пути и переписать конкретную часть, чтобы не получать доступ к внутренним компонентам в долгосрочной перспективе.

Однако для Groovy вам придется добавить такую ​​опцию для каждого пакета, который использует сценарий, без возможности переписать код, чтобы в конечном итоге избавиться от проблемы.

Что не означает, что не может быть действительно проблемных частей, получающих доступ к внутренностям, возможно, случайно. Просто вы не можете отличить их от законного использования классов.

Маловероятно, что поведение, продолжающееся с 2007 года, будет исправлено или что такое исправление может быть сделано без нарушения чего-либо в других местах, то есть непреднамеренных обращений, упомянутых выше, или даже преднамеренных, поскольку некоторые люди считают это особенностью.

Спасибо. Для тех, кто посетит эту ветку в будущем, я работал со старыми версиями Groovy и Rest-Assured. Проблема решена после обновления до надежной версии 5.3.0, заводной версии 4.0.9. Очень ценю услуги сообщества stackoverflow.

Dhiraj Shetty 18.02.2023 06:22

Другие вопросы по теме