从openjdk11访问com.sun。*类

时间:2019-03-05 20:03:56

标签: java

我有一个Spring Boot应用程序,我想使用类com.sun.management.ThreadMXBean和方法getThreadAllocatedBytes来收集有关我的应用程序中已分配字节的信息。我对其进行了docker化,并在dockerfile中使用了OpenJDK 11,因为无法对Oracle JDK进行dockerized。我正在使用docker image jboss/base-jdk:11,并将应用程序部署在Wildfly 16中。

不幸的是,OpenJDK不支持com.sun.*软件包。有什么办法可以解决此问题并在OpenJDK中使用com.sun.management.ThreadMXBean.getThreadAllocatedBytes

2 个答案:

答案 0 :(得分:4)

因此,我刚刚下载了OpenJDK 11并提取了其来源。
在里面,我发现了ThreadImpl,它实现了java.lang.management.ThreadMXBean

enter image description here

事实上,您可以在下面找到它

enter image description here

ThreadMXBean确实有一种getThreadAllocatedBytes方法

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;
}

答案 1 :(得分:3)

因此,这对我来说与AdoptJdk 11(它是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);
        }
    }
}

调用

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

此外,它在该docker映像中有效

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

并在docker中运行它:

docker build -t openjdktest .
docker run -it openjdktest

编辑

哦,似乎还有一个更简单的选择。只需将ThreadMXBean对象直接投射到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);
    }
}

即使没有--add-exports JVM参数,它也可以运行。