【问题标题】:JDK9: An illegal reflective access operation has occurred. org.python.core.PySystemStateJDK9:发生了非法反射访问操作。 org.python.core.PySystemState
【发布时间】:2018-02-24 02:31:54
【问题描述】:

我正在尝试使用 Java9 (JDK9) 运行 DMelt 程序 (http://jwork.org/dmelt/) 程序,它给了我以下错误:

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.python.core.PySystemState (file:/dmelt/jehep/lib/jython/jython.jar) to method java.io.Console.encoding()
WARNING: Please consider reporting this to the maintainers of org.python.core.PySystemState
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=permit 添加到脚本“dmelt.sh”的最后一行(我在 Linux 中使用 bash),但这并没有解决这个问题。我对此感到非常沮丧。我经常使用这个程序,很长一段时间。也许我永远不应该迁移到 JDK9

【问题讨论】:

    标签: java java-9 java-module


    【解决方案1】:

    解决这个问题的理想方法是

    将此情况报告给 org.python.core.PySystemState 的维护者

    并要求他们在未来修复此类反射访问。


    但是,如果默认模式允许非法反射访问,那么 让人们知道这一点很重要,这样人们就不会感到惊讶 这不再是未来版本中的默认模式。

    来自threads on the mailing list 之一:

    --illegal-access=permit
    

    这将是 JDK 9 的 默认 模式。它会在 每个显式模块都在所有未命名的模块中编码,即,在 类路径,就像今天的 --permit-illegal-access 一样。

    第一次非法反射访问操作会导致警告 已发出,与--permit-illegal-access 一样,但不发出警告 在那之后。此单个警告将描述如何启用 进一步的警告。

    --illegal-access=deny
    

    这将禁用所有非法反射访问操作,除了 那些由其他命令行选项启用的,例如--add-opens。 此将在未来版本中成为默认模式。

    通过明智地使用--add-exports--add-opens 选项,可以像以前一样避免任何模式下的警告消息。


    因此,当前可用的临时解决方案是使用--add-exports 作为docs 中提到的VM 参数:

    --add-exports module/package=target-module(,target-module)*
    

    更新模块到 export 包到 target-module,不管 模块声明。 target-module 可以全部未命名导出到 所有未命名的模块。

    这将允许target-module 访问package 中的所有公共类型。如果您想访问仍将被封装的 JDK 内部类,则必须使用 --add-opens 参数允许 深度反射

    --add-opens module/package=target-module(,target-module)*
    

    更新模块到 open 包到 target-module,不管模块 声明。

    在您当前访问java.io.Console 的情况下,您可以简单地将其添加为 VM 选项 -

    --add-opens java.base/java.io=ALL-UNNAMED
    

    另外,请注意上面链接的同一线程

    deny 成为默认模式时,我希望permit 至少在一个版本中仍受支持,以便开发人员可以继续迁移他们的代码。随着时间的推移,permitwarndebug 模式将被删除,--illegal-access 选项本身也将被删除。

    所以最好改变实现并遵循理想的解决方案。

    【讨论】:

      【解决方案2】:

      DMelt 似乎使用了 Jython,这个警告是 Jython 维护人员需要解决的问题。这里有一个跟踪它的问题: http://bugs.jython.org/issue2582

      【讨论】:

      • 看起来 Jython 2,7 开发人员也一无所知。他们上一次报告是在 2017 年 4 月。他们还没有解决这个问题。
      【解决方案3】:

      真正的问题是 JDK 中的问题。实际上没有非法访问,但是JDK方法trySetAccessible行为不端。这有望在未来的 JDK 版本中得到修复。

      尝试解决下面的答案link

      【讨论】:

      • “真正的问题是 JDK 的问题”,我在构建路径中查看了我的 JDK 设置。帮助我找出问题所在。
      【解决方案4】:

      为避免此错误,您需要将maven-war-plugin 重新定义为新的。例如:

      <plugins>
          . . .
          <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-war-plugin</artifactId>
              <version>3.2.2</version>
          </plugin>
      </plugins>
      

      适用于jdk-12

      【讨论】:

        【解决方案5】:

        根据这篇帖子http://bugs.jython.org/issue2582,Jython 开发人员没有任何实用的 jdk9 解决方案。 前面的解释似乎很长,想不通应该怎么做。我只希望 jdk9 的行为与 jdk1.4 - 1.8 完全相同,即完全保持沉默。 JVM 在向后可比性方面的优势。我完全可以在 JDK9 中有其他选项,但新功能不能破坏应用程序

        【讨论】:

        • 此问题需要更改侵入 java.io.Console 中私有编码方法的 Jython 代码。该警告提醒您,一旦阻止对 JDK 内部的访问,黑客就会中断。您当然可以通过打开 java.io 包进行深度反射 (--add-opens java.base/java.io=ALL-UNNAMED) 来解决它,但如果 Jython 解决了这个问题会更好。
        【解决方案6】:

        从Java update 9开始,出现“发生了非法反射访问操作”的警告。

        删除警告信息。您可以用 maven-war-plugin 替换 maven-compiler-plugin 和/或用 pom.xml 中的最新版本更新 maven-war-plugin。以下是 2 个示例:

        从以下位置更改版本:

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.4</version>
            ...
               
            ...
        </plugin>
        

        收件人:

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>3.3.1</version>
            ...
             ...
        </plugin>
        

        更改 artifactId 和版本自:

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.5.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
        

        到:

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.3.1</version>
                <executions>
                    <execution>
                        <id>prepare-war</id>
                        <phase>prepare-package</phase>
                        <goals>
                            <goal>exploded</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        

        当我重新运行 Maven Build 或 Maven Install 时,“发生了非法反射访问操作”消失了。

        【讨论】:

          【解决方案7】:

          也许下面的修复也适用于 java 9:

          在我的例子中,java open jdk 版本是 10.0.2 并且得到了同样的错误(发生了非法反射访问操作)。我在linux上将maven升级到了3.6.0版本,问题就消失了。

          【讨论】:

            【解决方案8】:

            在从事 Kotlin Spring 项目时来到这里。通过以下方式解决了该问题:

            cd /project/root/
            touch .mvn/jvm.config
            echo "--illegal-access=permit" >> .mvn/jvm.config
            

            【讨论】:

              【解决方案9】:

              最近的一些反馈。

              如java错误代码中所述

              WARNING: All illegal access operations will be denied in a future release
              

              这个未来版本是 JDK 17,其中启动器参数 --illegal-access 将停止工作。

              更多直接来自 Oracle 的信息可以在这里找到:JEP 403 link 1JEP 403 link 2

              进行此更改后,最终用户将无法再使用 --illegal-access 选项允许访问内部元素 JDK。 (此处提供了受影响的软件包列表。) sun.misc 和 sun.reflect 包仍将由 jdk.unsupported 模块,并且仍将打开以便代码可以访问 他们的非公开元素通过反射。其他 JDK 包不会 以这种方式打开。

              仍然可以使用 --add-opens 命令行选项,或 Add-Opens JAR 文件清单属性,用于打开特定的包。

              因此,--add-opens module/package=target-module(,target-module)* 解决方案和示例 --add-opens java.base/java.io=ALL-UNNAMED 将继续适用于 JDK 17 和未来版本,但 --illegal-access 不会。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2021-08-29
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2022-01-22
                • 1970-01-01
                • 2021-01-10
                相关资源
                最近更新 更多