Отражающий вызов в JDK 17 против интерфейса

Я переношу свой проект на JDK 17. Все работает отлично, кроме одного:

      class org.aldan3.util.TemplateEngine cannot access class sun.nio.fs.UnixPath (in module java.base) because module java.base does not export sun.nio.fs to unnamed module @c12d4d

Насколько я понимаю, класс подчеркивания, реализующий интерфейс Path, не может быть назван из-за ограниченного объема. Как я могу объявить рефлексивный вызов с помощью интерфейса Path? Или есть еще одна хитрость?

Исключение:

java.lang.IllegalAccessException: класс org.aldan3.util.TemplateEngine не может получить доступ к классу sun.nio.fs.UnixPath (в модуле java.base), поскольку модуль java.base не экспортирует sun.nio.fs в безымянный модуль @c12d4d в java.base / jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:392) в java.base / java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:674) в java.base / java.lang. Reflect.Method.invoke(Method.java:560) в org.aldan3.util.TemplateEngine.processMethodCall(TemplateEngine.java:1731) в org.aldan3.util.TemplateEngine.process(TemplateEngine.java:1397) в org.aldan3 .util.TemplateEngine.process(TemplateEngine.java:852) в org.aldan3.util.TemplateEngine.processResource(TemplateEngine.java:259) в org.aldan3.util.TemplateEngine.process(TemplateEngine.java:392) в org. aldan3.util.TemplateEngine.processResource(TemplateEngine.java:259) в org.aldan3.util.TemplateEngine.process(TemplateEngine.java:432) в org.aldan3.util.TemplateEngine.processResource(TemplateEngine.java:259) в org.aldemplate3.util.T .process (TemplateEngine.java:280) в org.aldan3.servlet.BasePageService.processView(BasePageService.java:381) в org.aldan3.servlet.BasePageService.serve(BasePageService.java:222) в org.aldan3.servlet. FrontController.doRequest(FrontController.java:244) в org.aldan3.servlet.FrontController.service(FrontController.java:159) в javax.servlet.http.HttpServlet.service(HttpServlet.java:790) в rogletbAppSweb.$SimpleFilterChain.doFilter(WebAppServlet.java:3599) в rogatkin.web.WebAppServlet$WebAppContextFilter.doFilter(WebAppServlet.java:3219) в rogatkin.web.WebAppServlet$SimpleFilterChain.doava3571) в rogatkin.web.WebAppServlet.service(WebAppServlet.java:1464) в Acme.Serve.Serve$ServeConnection.runServlet(Serve.java:2407) в Acme.Serve.Serve$ServeConnection.parseRequest:2326.java ) в Acme.Serve.Serve$ServeConnection.run(Serve.java:2110) в Acme.Utils$ThreadPool$PooledThread.run(Utils.java:1238) в java.base / java.lang.Thread.run(Thread.java:833)

Источник исключения

Добавление объекта на карту, а затем его методы будут вызываться с использованием отражения

1 ответ

Вам следует связаться с автором org.aldan3.util.TemplateEngine.

По-видимому, он использует отражение, чтобы попытаться получить доступ к внутренностям sun.nio.fs.UnixPath. Так не должно быть. Такой доступ к внутреннему устройству всегда был плохой идеей. В более поздних версиях Java они перемещались, чтобы приложения не могли этого сделать. (Подробнее см. )

Я не могу сразу понять, почему этот код выполняет этот незаконный доступ. Но должен быть способ реализовать функциональность (какой бы то ни было) таким образом, чтобы избежать проблемы.

  • Если вы являетесь автором, если вы объясните, что делает этот код и почему, то, возможно, кто-нибудь предложит альтернативу.

  • Если вы не являетесь автором (и у вас нет времени и / или навыков, чтобы глубоко погрузиться в код и т. Д.), Вам лучше всего поднять «проблему» на сайте Github для программного обеспечения. Затем решайте, что делать ... в зависимости от ответа автора.


Насколько я понимаю, класс подчеркивания, реализующий интерфейс Path, не может быть назван из-за ограниченного объема. Как я могу объявить рефлексивный вызов с помощью интерфейса Path? Или есть еще одна хитрость?

Это можно сделать с помощью обходного пути, описанного в примечаниях к выпуску Java 17 :

JEP 403: строгая инкапсуляция внутренних компонентов JDK (JDK-8266851)core-libs

Тщательно инкапсулируйте все внутренние элементы JDK, за исключением важных внутренних API, таких как sun.misc.Unsafe.

С этим изменением опция запуска java --illegal-accessустарело. При использовании в командной строке выдается предупреждающее сообщение, в противном случае не имеет никакого эффекта. Существующий код, который должен использовать внутренние классы, методы или поля JDK, по-прежнему можно заставить работать, используя --add-opens вариант запуска или Add-Opens Атрибут манифеста JAR-файла для открытия определенных пакетов.

Для получения дополнительных сведений см. JEP 403.JEP 403.

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

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