If you run in a restricted JVM that has no JMX, Micrometer falls in a heap:
Caused by: java.lang.NoClassDefFoundError: Could not initialize class sun.management.ManagementFactoryHelper
at java.lang.management.ManagementFactory.getMemoryPoolMXBeans(ManagementFactory.java:387) ~[na:1.8.0_102-internal]
at io.micrometer.core.instrument.binder.jvm.JvmGcMetrics.<init>(JvmGcMetrics.java:76) ~[micrometer-core-1.3.2.jar!/:1.3.2]
at io.micrometer.core.instrument.binder.jvm.JvmGcMetrics.<init>(JvmGcMetrics.java:72) ~[micrometer-core-1.3.2.jar!/:1.3.2]
at org.springframework.boot.actuate.autoconfigure.metrics.JvmMetricsAutoConfiguration.jvmGcMetrics(JvmMetricsAutoConfiguration.java:48) ~[spring-boot-actuator-autoconfigure-2.2.4.RELEASE.jar!/:2.2.4.RELEASE]
Seems like we could be more defensive, but this is probably not the end of the problem. E.g. I found (from running the Petlinic in Tiny Core Linux) that eh-cache fails in the same way. Also webjars locator has an out of date dependency on the classgraph dependency, and that fails unless you update it.
Comment From: dsyer
TomcatMetricsBinder
is another failure point in Spring Boot actuators:
java.lang.NoClassDefFoundError: Could not initialize class sun.management.ManagementFactoryHelper
at java.lang.management.PlatformComponent$1.getMXBeans(PlatformComponent.java:72) ~[na:1.8.0_102-internal]
at java.lang.management.PlatformComponent.getMXBeans(PlatformComponent.java:377) ~[na:1.8.0_102-internal]
at java.lang.management.ManagementFactory.getPlatformMBeanServer(ManagementFactory.java:472) ~[na:1.8.0_102-internal]
at io.micrometer.core.instrument.binder.tomcat.TomcatMetrics.getMBeanServer(TomcatMetrics.java:83) ~[micrometer-core-1.3.2.jar!/:1.3.2]
at io.micrometer.core.instrument.binder.tomcat.TomcatMetrics.<init>(TomcatMetrics.java:61) ~[micrometer-core-1.3.2.jar!/:1.3.2]
at org.springframework.boot.actuate.metrics.web.tomcat.TomcatMetricsBinder.onApplicationEvent(TomcatMetricsBinder.java:60) ~[spring-boot-actuator-2.2.4.RELEASE.jar!/:2.2.4.RELEASE]
...
Comment From: dsyer
I was able to launch the Petclinic with spring.cache.type=none
and
spring.autoconfigure.exclude=org.springframework.boot.actuate.autoconfigure.metrics.JvmMe
tricsAutoConfiguration,org.springframework.boot.actuate.autoconfigure.metrics.SystemMetricsAutoConfiguration,org.springframework.boot.actuate.autoconfigure.metrics.web.tomcat.TomcatMetricsAutoConfiguration
and also upgrading to
<dependency>
<groupId>io.github.classgraph</groupId>
<artifactId>classgraph</artifactId>
<version>4.8.69</version>
</dependency>
Comment From: philwebb
It's interesting that the java.lang.management.ManagementFactory
class is available, but the missing class is sun.management.ManagementFactoryHelper
. I don't think we can do a simple @ConditionalOnClass
for that. We could investigate a @ConditionalOnJmx
if this situation is common.
@dsyer Where can we get the JVM that you're using? Can you provide us the steps we need to follow to replicate the issue?
Comment From: dsyer
The JVM is the one distributed in Tiny Core Linux. You can reproduce the problem by installing that and running tce-load -wi openjdk-8-jre
. I think it has a bug though - the native library is not compiled properly or something. I'm trying to contact the maintainers.
Comment From: philwebb
Should we close this one then for now?
Comment From: dsyer
I’m not sure. I still think maybe there’s an angle, even with a non-broken JVM that simply doesn’t have JMX. I’ll find out if the module system allows that, and if it does it might still be a good idea to provide actuators (for instance) that work when JMX isn’t available.
Comment From: dsyer
You definitely can prepare a Java runtime without java.management
and it seems like a reasonable thing to want to do. The exception is more expected - just a missing class:
$ jlink --no-header-files --no-man-pages --add-modules java.base --output test-runtime
$ test-runtime/bin/java -cp . Test
Exception in thread "main" java.lang.NoClassDefFoundError: java/lang/management/ManagementFactory
at Test.main(Test.java:5)
Caused by: java.lang.ClassNotFoundException: java.lang.management.ManagementFactory
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:602)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
... 1 more
Comment From: eddumelendez
hi, wondering if checking with @ConditionalOnClass(java.lang.management.ManagementFactory.class)
at JmxAutoConfiguration
and JmxMetricsExportAutoConfiguration
will be enough or creating @ConditionalOnJmx
as Phil proposed is the way to go, if so should I take advantage of JmxUtils
?. I am interested to work on this. I guess the target branch should be 2.3.x
, right? Cheers.