当前位置: 首页 > 知识库问答 >
问题:

quarkus optaplanner非法反射呼叫

鲁辉
2023-03-14

我已将JDK升级到版本17。现在,当我尝试在Quarkus上运行optaplanner来运行参数化单元测试时,我得到以下stacktrace:

java.lang.ExceptionInInitializerError
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make field private transient java.util.NavigableMap java.util.TreeSet.m accessible: module java.base does not "opens java.util" to unnamed module @724b93a8

[ERROR] org.m.s.c.score.constraints.SecConflictTest.secConflictTest(String, int, Agent)[2]  Time elapsed: 0.011 s  <<< ERROR!
java.lang.NoClassDefFoundError: Could not initialize class com.thoughtworks.xstream.converters.collections.TreeSetConverter$Reflections

[ERROR] org.m.s.c.score.constraints.SecConflictTest.secConflictTest(String, int, Agent)[3]  Time elapsed: 0.014 s  <<< ERROR!
java.lang.NoClassDefFoundError: Could not initialize class com.thoughtworks.xstream.converters.collections.TreeSetConverter$Reflections

在读了一点关于这种问题的内容后,我补充道

--add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.text=ALL-UNNAMED --add-opens java.desktop/java.awt.font=ALL-UNNAMED

在以下部分中到我的Maven POM:Quarkus-maven-plugin config和maven-surefire-config

        <plugins>
            <plugin>
                <groupId>${quarkus.platform.group-id}</groupId>
                <artifactId>quarkus-maven-plugin</artifactId>
                <version>${quarkus.platform.version}</version>
                <extensions>true</extensions>
                <configuration>
                    <source>${maven.compiler.source}</source>
                    <target>${maven.compiler.target}</target>
                    <compilerArgs>
                        <arg>--enable-preview --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.text=ALL-UNNAMED --add-opens java.desktop/java.awt.font=ALL-UNNAMED</arg>
                    </compilerArgs>
                    <jvmArgs>--enable-preview --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.text=ALL-UNNAMED --add-opens java.desktop/java.awt.font=ALL-UNNAMED</jvmArgs>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>build</goal>
                            <goal>generate-code</goal>
                            <goal>generate-code-tests</html" target="_blank">goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${compiler-plugin.version}</version>
                <configuration>
                    <parameters>${maven.compiler.parameters}</parameters>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>${surefire-plugin.version}</version>
                <configuration>
                    <argLine>
                        --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.text=ALL-UNNAMED --add-opens java.desktop/java.awt.font=ALL-UNNAMED
                    </argLine>
                    <systemPropertyVariables>
                        <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
                        <maven.home>${maven.home}</maven.home>
                    </systemPropertyVariables>
                </configuration>
            </plugin>
        </plugins>

并且在配置文件本机的maven-故障安全-插件配置中:

<profiles>
        <profile>
            <id>native</id>
            <activation>
                <property>
                    <name>native</name>
                </property>
            </activation>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-failsafe-plugin</artifactId>
                        <version>${surefire-plugin.version}</version>
                        <executions>
                            <execution>
                                <goals>
                                    <goal>integration-test</goal>
                                    <goal>verify</goal>
                                </goals>
                                <configuration>
                                    <argLine>
                                        --add-opens java.base/java.lang.reflect=ALL-UNNAMED
                                        --add-opens java.base/java.util=ALL-UNNAMED
                                        --add-opens java.base/java.text=ALL-UNNAMED
                                        --add-opens java.desktop/java.awt.font=ALL-UNNAMED
                                    </argLine>
                                    <systemPropertyVariables>
                                        <native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
                                        <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
                                        <maven.home>${maven.home}</maven.home>
                                    </systemPropertyVariables>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
            <properties>
                <quarkus.package.type>native</quarkus.package.type>
            </properties>
        </profile>
    </profiles>

它确实按预期工作:测试运行正常,但我“丢失”了quarkus的实时重新加载功能如果我更改代码中的任何内容并再次调用WS,则错误如下:

Error restarting Quarkus
java.lang.IllegalArgumentException: error: invalid flag: --enable-preview --add-opens
            java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens
            java.base/java.text=ALL-UNNAMED --add-opens java.desktop/java.awt.font=ALL-UNNAMED

我正在寻找一种允许Quarkus with Optaplanner在Java 17上运行的配置,参数化测试运行良好,实时重新加载仍在工作。关于信息,对于简单的测试(无参数化),它不需要特定的--add open配置就可以工作。

以下是引导我进行第一次修复的帖子:https://github.com/quarkusio/quarkus/issues/10303#issuecomment-666492921

共有2个答案

殳越
2023-03-14

我发现这个问题有两个可能的原因(我看不出是哪一个):

>

  • 您正在使用OptaPlanner 7。修复:升级到OptaPlanner 8,它使用JAXB而不是XStream。OptaPlanner 8的Quarkus扩展稳定可靠(7分之一的扩展不稳定)。

    在调用OptaPlanner之前,您正在使用XStream加载数据集,可能是通过使用optaplanner-持久性-xstream。这是JDK 17的XStream问题。(参见Lukas的评论。)我希望升级到新版本的XStream可以修复它。

  • 甄文彬
    2023-03-14

    我实际上添加了--添加打开。。。指向破坏livereload的javac参数的行。

    通过仅在Quakus-maven-plugin上的JVMArgs上使用此add-open参数,它可以按预期工作。和Live Reload也在工作。

    顺便说一句,我仍在寻找一个解决方案,不必添加任何add-open参数

     类似资料:
    • JDK11+spring批处理 有人知道那些警告是什么意思吗: 警告:发生了非法的反射访问操作警告:org.springframework.cglib.core.reflectutils$1(jar:file:/users/boru/downloads/spcljr/build/libs/spcljr-0.0.1-snapshot.jar!/boot-inf/lib/spring-core-5.0

    • 问题内容: 我正在尝试模拟一些基于反射的方法。您可以在下面看到详细信息, 被测课程 测试 } 要么 但是,测试失败,并显示NullPointerException。我知道我在嘲笑概念上做错了什么,但是我不明白这是什么。您能否对此加以说明,并建议我如何测试此方法? 谢谢。 问题答案: 您需要一个Method对象和一个Class对象。根据您的评论,Mockito无法模拟方法,因此您需要一个真正的方法。

    • 我正在使用反射来调用java.util.Stream.Stream上的方法,但由于实际实现(ReferencePipeline等)具有运行的实际代码,因此在调用时会收到非法的反射访问警告,如果没有该调用,它将无法工作。我想知道是否有一种方法可以自动将其委托给一个访问不非法的超级方法?也就是说,我想调用,其中是合法的,而不是或任何实现。 编辑这里是一些代码。是通过反射获得的流的具体实例。

    • 在Java9中有很多关于非法反射访问的问题。 我发现了很多关于如何处理错误消息的讨论,但我想知道非法反射访问实际上是什么。 所以我的问题是: 我认为这与Java9中引入的封装原则有关,但我找不到一个解释,说明它们是如何联系在一起的,是什么触发了警告,以及在什么场景中。

    • 最近升级到Java11并开始执行回归检查。当前在尝试调用时出现非法反射访问错误。目前在Itext版本5.5.13上,但也在Itext 7.0.0上试用过,出现了相同的问题。 有人对如何修复Java-11和iText之间的兼容性问题有什么建议吗? 警告:发生了非法反射访问操作警告:com.itextpdf.io.source.ByteBufferRandomAccessSource$1(文件:...