Отражающий вызов в 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 внутренностей.