Search code examples
javajmxjava-modulejava-17illegalaccessexception

How do I give jmxterm access to sun.tools.jconsole.LocalVirtualMachine in Java 17?


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-opens instead of --add-exports in the java command even though I don't think that should be necessary
  • Setting the source to 17 in pom.xml
  • Adding --add-modules jdk.jconsole argument to the java command as well as to pom.xml

Is there something I am missing or is this just not possible?


Solution

  • In the 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
    

    You are passing the --add-exports flag as a program argument, rather than a VM argument.

    The flag should be passed before the -jar flag instead:

    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