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. I dockerized it and used OpenJDK 11 in the dockerfile, because Oracle JDK cannot be dockerized. I'm using docker image jboss/base-jdk:11
and deploy the application in a Wildfly 16.
Unfortunately OpenJDK does not support the com.sun.*
packages. Is there any way I can work around this problem and use com.sun.management.ThreadMXBean.getThreadAllocatedBytes
in an OpenJDK?
The class files created by Java 8 are still executable in Java 11; however, there have been other changes in the Java runtime (library changes, etc.) that might require modification of the code. These modifications may be made in Java 8 and compiled with Java 8 making it compatible with the Java 11 runtime.
In JDK 11, the Java EE and CORBA modules were removed.
In JDK 11, this is no longer an option. In this release, the JRE or Server JRE is no longer offered. Only the JDK is offered. Users can use jlink to create smaller custom runtimes.
It is based on the upstream OpenJDK 8u, OpenJDK 11u, and OpenJDK 17u projects and includes the Shenandoah Garbage Collector in all versions. Multi-platform - The Red Hat build of OpenJDK is now supported on Windows and RHEL.
Also, the OpenJDK Quality Group maintains a Quality Outreach wiki page that lists the status of testing of many Free Open Source Software (FOSS) projects against versions of OpenJDK. The Parallel garbage collector (Parallel GC) is the default GC in Java 8.
Now everything works fine with AdoptOpenJDK11 or opendjdk11 on windows systems. But on linux (ubnutu-64 bits or any ARM based linux environments) we got another class not found/No class def exceptions related to com.sun.java.swing.plaf.windows.WindowsLookAndFeel from the third party libraries we used.
Chapter 1. Red Hat build of OpenJDK overview The Red Hat build of OpenJDK is a free and open source implementation of the Java Platform, Standard Edition (Java SE). It is based on the upstream OpenJDK 8u, OpenJDK 11u, and OpenJDK 17u projects and includes the Shenandoah Garbage Collector in all versions.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With