JDK9:发生了非法的反射访问操作。org.python.core.PySystemState

58

我想要使用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

我该怎么办?我尝试在脚本 "dmelt.sh" 的最后一行添加 –illegal-access=permit(我正在Linux中使用bash),但这并没有解决这个问题。我对此非常沮丧。我经常使用这个程序,已经使用了很长时间了。也许我不应该升级到JDK9。

9个回答

46

解决这个问题的理想方式是:

向org.python.core.PySystemState的维护人员报告此问题,并要求他们在今后修复这种反射访问。

并请他们解决此类反射访问问题。


如果默认模式允许非法反射访问,那么必须让人们知道这一点,以便在将来的版本中不再使用默认模式时不会感到惊讶。

来自邮件列表上的一个讨论线程

--illegal-access=permit

这将是JDK 9的默认模式。它将所有显式模块中的每个包对所有未命名模块(即类路径上的代码)打开,就像今天的--permit-illegal-access一样。 第一个非法反射访问操作会发出警告,就像--permit-illegal-access一样,但在此之后不会发出任何警告。这个单一的警告将描述如何启用更多的警告。
--illegal-access=deny

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

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


因此,目前可用的临时解决方案是在VM参数中使用--add-exports,如docs中所述:
--add-exports module/package=target-module(,target-module)*

更新模块以将包导出到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选项本身也将被删除。

因此,更改实现并遵循理想解决方案更好。


6

据看,DMelt似乎使用了Jython,而这个警告是需要Jython维护人员去解决的。 在此有一个跟踪问题的链接:http://bugs.jython.org/issue2582


看起来Jython 2.7的开发人员也不知道怎么解决。他们最后一次报告是在2017年4月。他们没有解决这个问题。 - IraS

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


4

实际问题出现在JDK中。事实上,不存在非法访问,而是JDK方法trySetAccessible的行为不当。希望这将在未来的JDK版本中得到修复。

尝试解决以下答案链接


"真正的问题在于 JDK 的问题,仅通过这一点,我查看了我的构建路径中的 JDK 设置,帮助我找出了问题。" - Ram

2
根据这篇文章,Jython开发人员目前没有针对jdk9的实际解决方案。之前的解释过于冗长,难以搞清楚应该怎么做。我只希望jdk9的行为与jdk1.4-1.8完全相同,即完全静默。JVM在向后兼容方面很强大。我完全可以接受在JDK9中添加其他选项,但新功能不能破坏应用程序。请注意保留HTML标签。

3
这个问题需要修改Jython代码,因为它正在入侵java.io.Console的私有编码方法。警告提醒我们,一旦阻止访问JDK内部,这种入侵将不起作用。当然,您可以通过打开java.io包进行深度反射(--add-opens java.base/java.io=ALL-UNNAMED)来解决这个问题,但最好是Jython解决这个问题。 - Alan Bateman

1
自Java更新至9以来,“发生非法反射访问操作”警告会出现。
为了消除警告信息,您可以在pom.xml中使用maven-war-plugin替换maven-compiler-plugin和/或将maven-war-plugin更新至最新版本。以下是两个示例:
将版本从:
<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 和 version 从:

<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>

TO:

    <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时,“非法反射访问操作已发生”就消失了。

0

一些最近的反馈。

如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将不再适用。


0
也许下面的修复方法同样适用于Java 9:
在我的情况下,Java OpenJDK版本是10.0.2,并出现了相同的错误(发生了非法反射访问操作)。我在Linux上升级了Maven到3.6.0版本,问题就解决了。

0

在开发 Kotlin Spring 项目时遇到了问题,通过以下方式解决:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接