[英]Access com.sun.* classes from openjdk11
I have a Spring Boot application and I want to use the class com.sun.management.ThreadMXBean
, and the method getThreadAllocatedBytes
to collect information about allocated bytes in my application. 我有一个Spring Boot应用程序,我想使用类
com.sun.management.ThreadMXBean
,方法getThreadAllocatedBytes
来收集有关我的应用程序中已分配字节的信息。 I dockerized it and used OpenJDK 11 in the dockerfile, because Oracle JDK cannot be dockerized. 我将它停靠并在dockerfile中使用OpenJDK 11,因为Oracle JDK无法进行停靠。 I'm using docker image
jboss/base-jdk:11
and deploy the application in a Wildfly 16. 我正在使用docker image
jboss/base-jdk:11
并在Wildfly 16中部署该应用程序。
Unfortunately OpenJDK does not support the com.sun.*
packages. 不幸的是,OpenJDK不支持
com.sun.*
包。 Is there any way I can work around this problem and use com.sun.management.ThreadMXBean.getThreadAllocatedBytes
in an OpenJDK? 有什么方法可以解决这个问题,并在OpenJDK中使用
com.sun.management.ThreadMXBean.getThreadAllocatedBytes
?
So, I just downloaded OpenJDK 11
and extracted its sources. 所以,我刚刚下载了
OpenJDK 11
并提取了它的来源。
Inside I found ThreadImpl
, which implements java.lang.management.ThreadMXBean
在里面我找到了
ThreadImpl
,它实现了java.lang.management.ThreadMXBean
And infact you can find it under 事实上你可以找到它
ThreadMXBean
has indeed a getThreadAllocatedBytes
method 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;
}
So, this worked for me with AdoptJdk 11 (which is a build of OpenJdk): 所以,这对我有用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);
}
}
}
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 此外,在该docker镜像中它可以工作
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中运行它:
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
: 只需将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);
}
}
This can be run, even without the --add-exports
JVM argument. 即使没有
--add-exports
JVM参数,也可以运行它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.