I am trying to use jmxterm with Eclipse Temurin Java 17, but because of the module encapsulation changes in Java 17, jmxterm no longer has access to the class sun.tools.jconsole.LocalVirtualMachine in the jdk.jconsole module. So, running the following command:
printf "open 25522\n" | java -jar jmxterm-1.0.4-uber.jar -v verbose
outputs the following exception:
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
To fix this, I thought I would have to recompile jmxterm with the --add-exports option, so to do that, I added this plugin to the 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>
and I also had to add this config to the surefire plugin:
<argLine>
--add-opens java.base/java.lang=ALL-UNNAMED
--add-opens java.management/javax.management.openmbean=ALL-UNNAMED
</argLine>
I have verified that Maven is using the correct JDK to build 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"
So with these changes I was able to build a new jmxterm uber jar with mvn package.
I then tried to run my new jmxterm jar with --add-exports using this command:
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
but it still threw the same exception as above.
Other things I have tried that also didn't work:
- Using
--add-opensinstead of--add-exportsin thejavacommand even though I don't think that should be necessary - Setting the
sourceto 17 inpom.xml - Adding
--add-modules jdk.jconsoleargument to thejavacommand as well as topom.xml
Is there something I am missing or is this just not possible?
In the command:
You are passing the
--add-exportsflag as a program argument, rather than a VM argument.The flag should be passed before the
-jarflag instead: