Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access com.sun.* classes from openjdk11

Tags:

java

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?

like image 663
Cornelia Neumüller Avatar asked Mar 05 '19 20:03

Cornelia Neumüller


People also ask

Can Java 8 programs run on Java 11?

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.

What is removed in Java 11?

In JDK 11, the Java EE and CORBA modules were removed.

Does Jdk 11 release offer separate JRE?

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.

What versions of OpenJDK are there?

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.

Where can I find the status of testing of OpenJDK projects?

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.

Does adoptopenjdk11 work on Linux?

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.

What is red hat build of OpenJDK?

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.


1 Answers

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.

like image 171
chrisn Avatar answered Oct 05 '22 23:10

chrisn