Skip to content

Commit 1c61ab1

Browse files
committed
Polish ProcessInfo
Signed-off-by: Dmytro Nosan <[email protected]>
1 parent 8039030 commit 1c61ab1

File tree

1 file changed

+27
-9
lines changed
  • spring-boot-project/spring-boot/src/main/java/org/springframework/boot/info

1 file changed

+27
-9
lines changed

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/info/ProcessInfo.java

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2024 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -20,6 +20,9 @@
2020
import java.lang.management.MemoryMXBean;
2121
import java.lang.management.MemoryUsage;
2222
import java.lang.management.PlatformManagedObject;
23+
import java.lang.reflect.Method;
24+
25+
import org.springframework.util.ClassUtils;
2326

2427
/**
2528
* Information about the process of the application.
@@ -30,6 +33,11 @@
3033
*/
3134
public class ProcessInfo {
3235

36+
private static final String VIRTUAL_THREAD_SCHEDULER_CLASS = "jdk.management.VirtualThreadSchedulerMXBean";
37+
38+
private static final boolean VIRTUAL_THREAD_SCHEDULER_CLASS_PRESENT = ClassUtils
39+
.isPresent(VIRTUAL_THREAD_SCHEDULER_CLASS, null);
40+
3341
private static final Runtime runtime = Runtime.getRuntime();
3442

3543
private final long pid;
@@ -85,14 +93,18 @@ public MemoryInfo getMemory() {
8593
*/
8694
@SuppressWarnings("unchecked")
8795
public VirtualThreadsInfo getVirtualThreads() {
96+
if (!VIRTUAL_THREAD_SCHEDULER_CLASS_PRESENT) {
97+
return null;
98+
}
8899
try {
89-
Class<PlatformManagedObject> mxBeanClass = (Class<PlatformManagedObject>) Class
90-
.forName("jdk.management.VirtualThreadSchedulerMXBean");
91-
Object bean = ManagementFactory.getPlatformMXBean(mxBeanClass);
92-
return new VirtualThreadsInfo((Integer) mxBeanClass.getMethod("getMountedVirtualThreadCount").invoke(bean),
93-
(Long) mxBeanClass.getMethod("getQueuedVirtualThreadCount").invoke(bean),
94-
(Integer) mxBeanClass.getMethod("getParallelism").invoke(bean),
95-
(Integer) mxBeanClass.getMethod("getPoolSize").invoke(bean));
100+
Class<PlatformManagedObject> mxbeanClass = (Class<PlatformManagedObject>) ClassUtils
101+
.forName(VIRTUAL_THREAD_SCHEDULER_CLASS, null);
102+
PlatformManagedObject mxbean = ManagementFactory.getPlatformMXBean(mxbeanClass);
103+
int mountedVirtualThreadCount = invokeMethod(mxbeanClass, mxbean, "getMountedVirtualThreadCount");
104+
long queuedVirtualThreadCount = invokeMethod(mxbeanClass, mxbean, "getQueuedVirtualThreadCount");
105+
int parallelism = invokeMethod(mxbeanClass, mxbean, "getParallelism");
106+
int poolSize = invokeMethod(mxbeanClass, mxbean, "getPoolSize");
107+
return new VirtualThreadsInfo(mountedVirtualThreadCount, queuedVirtualThreadCount, parallelism, poolSize);
96108
}
97109
catch (ReflectiveOperationException ex) {
98110
return null;
@@ -111,6 +123,12 @@ public String getOwner() {
111123
return this.owner;
112124
}
113125

126+
@SuppressWarnings("unchecked")
127+
private <T> T invokeMethod(Class<?> mxbeanClass, Object mxbean, String name) throws ReflectiveOperationException {
128+
Method method = mxbeanClass.getMethod(name);
129+
return (T) method.invoke(mxbean);
130+
}
131+
114132
/**
115133
* Virtual threads information.
116134
*
@@ -126,7 +144,7 @@ public static class VirtualThreadsInfo {
126144

127145
private final int poolSize;
128146

129-
public VirtualThreadsInfo(int mounted, long queued, int parallelism, int poolSize) {
147+
VirtualThreadsInfo(int mounted, long queued, int parallelism, int poolSize) {
130148
this.mounted = mounted;
131149
this.queued = queued;
132150
this.parallelism = parallelism;

0 commit comments

Comments
 (0)