Bug 263881

Summary: java/openjdk17-jre Exception: Thread CPU time measurement is not supported
Product: Ports & Packages Reporter: indgy <me>
Component: Individual Port(s)Assignee: freebsd-java (Nobody) <java>
Status: New ---    
Severity: Affects Some People CC: borjam, lwhsu, michael.osipov, olivier, otis, ronald
Priority: --- Flags: bugzilla: maintainer-feedback? (java)
Version: Latest   
Hardware: amd64   
OS: Any   

Description indgy 2022-05-09 14:48:42 UTC
Using OpenJDK17-JRE with GoCD Server (Zip version) from here:
https://download.gocd.org/binaries/22.1.0-13913/generic/go-server-22.1.0-13913.zip

GoCD is a CI/CD server.

GoCD Server fails to run correctly when running a job in a Pipeline.

Downgrading to OpenJDK11-JRE fixes the issue, the above error no longer appears.

The following error seems to be the culprit.

java.lang.UnsupportedOperationException: Thread CPU time measurement is not supported.
	at java.management/sun.management.ThreadImpl.verifyThreadCpuTime(Unknown Source)
	at java.management/sun.management.ThreadImpl.getThreadCpuTime(Unknown Source)
	at jdk.management/com.sun.management.internal.HotSpotThreadImpl.getThreadCpuTime(Unknown Source)
	at java.management/sun.management.ThreadImpl.getThreadCpuTime(Unknown Source)
	at com.thoughtworks.go.server.service.support.DaemonThreadStatsCollector.captureStats(DaemonThreadStatsCollector.java:33)
	at com.thoughtworks.go.server.messaging.activemq.JMSMessageListenerAdapter.runImpl(JMSMessageListenerAdapter.java:82)
	at com.thoughtworks.go.server.messaging.activemq.JMSMessageListenerAdapter.run(JMSMessageListenerAdapter.java:63)
	at java.base/java.lang.Thread.run(Unknown Source)

Please drop me an email if you want me to setup an reproducable example.

Thank you
Comment 1 indgy 2022-05-09 19:37:20 UTC
As suggested on the Discord chat by Genesys the issue may be related to this:

https://github.com/battleblow/jdk17u/commit/6f2be9c6086cf2d45190c1c8b862a1e143a43de5


Using OpenJDK16 the issue does not occur and the app works as expected.
Comment 2 indgy 2022-05-10 12:14:20 UTC
@genesys also provided minimal code too reproduce, this works in v16 but fails under v17

echo "
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;
ThreadMXBean tb = ManagementFactory.getThreadMXBean();
System.out.println(tb.getThreadCpuTime(Thread.currentThread().getId())); " | JAVA_VERSION=17 jshell -
Comment 3 Olivier Cochard freebsd_committer freebsd_triage 2023-09-02 16:30:23 UTC
Same with regression with JDK 19
Comment 4 Borja Marcos 2023-09-06 11:01:15 UTC
FYI: 

Confirmed for example with the 7.5 versions of UniFi Controller (net-mgmt/unifi7).

They have switched to Java 17 as a minimum requirement and it doesn´t work with the current OpenJDK 17 for FreeBSD.

----
[2023-07-18 11:17:42,903] <webapi-8> ERROR [dispatcher] - Servlet.service() for servlet [dispatcher] in context with path [] threw exception [Request processing failed; nested exception is com.google.common.util.concurrent.UncheckedExecutionException: java.lang.UnsupportedOperationException: Current thread CPU time measurement is not supported.] with root cause
java.lang.UnsupportedOperationException: Current thread CPU time measurement is not supported.
----

I reported it to Ubiquiti as those functions are optional and they should check for availability before trying to use them, but I guess many other programs can fail in a similar way.
Comment 5 Juraj Lutter freebsd_committer freebsd_triage 2023-10-09 15:00:49 UTC
See review D42130 (I'm already running this with the recent unifi7 that is not yet committed).
Comment 6 Juraj Lutter freebsd_committer freebsd_triage 2023-10-09 15:01:36 UTC
(In reply to Juraj Lutter from comment #5)
This also needs to be adapted for the other OpenJDKs (I only did it for OpenJDK17 as it's the one I will need for net-mgmt/unifi7 update).
Comment 7 Borja Marcos 2023-10-10 06:48:02 UTC
(In reply to Juraj Lutter from comment #5)

Ubiquiti made changes from version 7.5.185 per my suggestion. Since 7.5.185 it works.

The Thread CPU measurement functions are an optional interface and Java documentation recommends to check for availability before use. So, relying on it without checking is a portability problem.

That said of course it´s better to have this interface available as some other applications will surely fail.
Comment 8 Juraj Lutter freebsd_committer freebsd_triage 2023-10-10 06:55:45 UTC
(In reply to Borja Marcos from comment #7)
That's probably true, but with the recent "RELEASE" (7.5.176) it just does not work. That's why I aimed to make a "copy" of Linux implementation (in fact, pthread_getcpuclockid() is POSIX function, available in FreeBSD since 10.0.
Comment 9 Ronald Klop freebsd_committer freebsd_triage 2024-03-25 14:09:48 UTC
According to this comment this issue is already resolved since 17.0.9.
https://reviews.freebsd.org/D42130#965940

The testcase from comment #2 also works on my RPI4 (FreeBSD 15/aarch64).

echo "
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;
ThreadMXBean tb = ManagementFactory.getThreadMXBean();
System.out.println(tb.getThreadCpuTime(Thread.currentThread().getId())); " | JAVA_VERSION=17 jshell -
Mar 25, 2024 3:05:43 PM java.util.prefs.FileSystemPreferences$1 run
INFO: Created user preferences directory.
667756203

Can we close the issue?