Access com.sun.* classes from openjdk11

So, I just downloaded OpenJDK 11 and extracted its sources.
Inside I found ThreadImpl, which implements java.lang.management.ThreadMXBean

enter image description here

And infact you can find it under

enter image description here

ThreadMXBean has indeed a getThreadAllocatedBytes method

protected long[] getThreadAllocatedBytes(long[] ids) {
    boolean verified = verifyThreadAllocatedMemory(ids);

    long[] sizes = new long[ids.length];
    java.util.Arrays.fill(sizes, -1);

    if (verified) {
        getThreadAllocatedMemory1(ids, sizes);
    }
    return sizes;
}

So, this worked for me with AdoptJdk 11 (which is a build of OpenJdk):

import java.lang.management.ManagementFactory;
import java.lang.reflect.Method;

import java.lang.management.ThreadMXBean;

public class Test {
    public static void main(String[] args) {
        ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); 
        try { 
            Method getBytes = threadMXBean.getClass().getMethod("getThreadAllocatedBytes", long.class); 
            getBytes.setAccessible(true); 

            long threadId = Thread.currentThread().getId();
            long bytes = (long)getBytes.invoke(threadMXBean, threadId);
            System.out.println(bytes);
        } catch (Throwable e) { 
            System.out.println(e);
        }
    }
}

Invoke with

C:\workspaces\devtools\jdks\adoptjdk\jdk-11.0.2+9\bin\javac Test.java
C:\workspaces\devtools\jdks\adoptjdk\jdk-11.0.2+9\bin\java --add-exports jdk.management/com.sun.management.internal=ALL-UNNAMED Test

Also, in that docker image it works

FROM jboss/base-jdk:11
COPY . /app/
WORKDIR /app
CMD java --add-exports jdk.management/com.sun.management.internal=ALL-UNNAMED Test

And run it in docker:

docker build -t openjdktest .
docker run -it openjdktest

EDIT

Oh, there seems to be an even simpler alternative. Just cast your ThreadMXBean object directly to com.sun.management.ThreadMXBean:

import java.lang.management.ManagementFactory;
import com.sun.management.ThreadMXBean;

public class Test {
    public static void main(String[] args) {
        ThreadMXBean threadMXBean = (ThreadMXBean)ManagementFactory.getThreadMXBean(); 
        long bytes = threadMXBean.getThreadAllocatedBytes(Thread.currentThread().getId());
        System.out.println(bytes);
    }
}

This can be run, even without the --add-exports JVM argument.

Tags:

Java