我尝试将 jmxterm 与 Eclipse Temurin Java 17 一起使用,但由于 Java 17 中的模块封装更改,jmxterm 不再能够访问 sun.tools.jconsole.LocalVirtualMachine
模块中的类
jdk.jconsole
。因此,运行以下命令:
printf "open 25522\n" | java -jar jmxterm-1.0.4-uber.jar -v verbose
输出以下异常:
java.lang.reflect.UndeclaredThrowableException
at jdk.proxy2/jdk.proxy2.$Proxy6.getAllVirtualMachines(Unknown Source)
at org.cyclopsgroup.jmxterm.jdk6.Jdk6JavaProcessManager.get(Jdk6JavaProcessManager.java:28)
at org.cyclopsgroup.jmxterm.SyntaxUtils.getUrl(SyntaxUtils.java:41)
at org.cyclopsgroup.jmxterm.cmd.OpenCommand.execute(OpenCommand.java:64)
at org.cyclopsgroup.jmxterm.cc.CommandCenter.doExecute(CommandCenter.java:161)
at org.cyclopsgroup.jmxterm.cc.CommandCenter.doExecute(CommandCenter.java:134)
at org.cyclopsgroup.jmxterm.cc.CommandCenter.execute(CommandCenter.java:176)
at org.cyclopsgroup.jmxterm.boot.CliMain.execute(CliMain.java:149)
at org.cyclopsgroup.jmxterm.boot.CliMain.main(CliMain.java:41)
Caused by: java.lang.IllegalAccessException: class org.cyclopsgroup.jmxterm.utils.WeakCastUtils$2 cannot access class sun.tools.jconsole.LocalVirtualMachine (in module jdk.jconsole) because module jdk.jconsole does not export sun.tools.jconsole to unnamed module @3bb50eaa
at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:392)
at java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:674)
at java.base/java.lang.reflect.Method.invoke(Method.java:560)
at org.cyclopsgroup.jmxterm.utils.WeakCastUtils$2.invoke(WeakCastUtils.java:136)
... 9 more
要解决此问题,我想我必须使用
--add-exports
选项重新编译 jmxterm,因此为此,我将此插件添加到 pom.xml:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<source>8</source>
<target>17</target>
<compilerArgs>
<arg>--add-exports</arg>
<arg>jdk.jconsole/sun.tools.jconsole=ALL-UNNAMED</arg>
</compilerArgs>
</configuration>
</plugin>
我还必须将此配置添加到 Surefire 插件中:
<argLine>
--add-opens java.base/java.lang=ALL-UNNAMED
--add-opens java.management/javax.management.openmbean=ALL-UNNAMED
</argLine>
我已经验证 Maven 使用正确的 JDK 来构建 jmxterm:
$ mvn --version
Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
Maven home: /opt/maven
Java version: 17.0.4.1, vendor: Eclipse Adoptium, runtime: /usr/lib/jvm/temurin-17-jdk
Default locale: en_CA, platform encoding: UTF-8
OS name: "linux", version: "3.10.0-1160.el7.x86_64", arch: "amd64", family: "unix"
通过这些更改,我能够使用
mvn package
构建一个新的 jmxterm uber jar。
然后我尝试使用以下命令运行我的新 jmxterm jar :
--add-exports
但它仍然抛出与上面相同的异常。
我尝试过的其他方法也不起作用:
在
printf "open 25522\n" | java -jar jmxterm/target/jmxterm-1.0.4-uber.jar --add-exports jdk.jconsole/sun.tools.jconsole=ALL-UNNAMED -v verbose
--add-opens
而不是 --add-exports
,尽管我认为这没有必要将 java
中的
source
设置为 17将
pom.xml
--add-modules jdk.jconsole
命令以及 java
pom.xml
您将
printf "open 25522\n" | java -jar jmxterm/target/jmxterm-1.0.4-uber.jar --add-exports jdk.jconsole/sun.tools.jconsole=ALL-UNNAMED -v verbose
标志作为程序参数传递,而不是 VM 参数。
该标志应在--add-exports
标志之前传递:
-jar
printf "open 25522\n" | java --add-exports jdk.jconsole/sun.tools.jconsole=ALL-UNNAMED -jar jmxterm/target/jmxterm-1.0.4-uber.jar -v verbose
:
--add-exports
请注意,这仅在您使用
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
…
<manifest>
<mainClass>org.cyclopsgroup.jmxterm.boot.CliMain</mainClass>
</manifest>
<manifestEntries>
<Add-Exports>jdk.jconsole/sun.tools.jconsole</Add-Exports>
</manifestEntries>
</archive>
</configuration>
</execution>
</plugin>
运行 JAR 时才有效,而对于其他命令(例如
java -jar jmxterm.jar
。另请参阅