Open shakuzen opened 1 week ago
class file has wrong version 65.0, should be 61.0 Please remove or make sure it appears in the correct subdirectory of the classpath.
micrometer-java21
is built using JDK21, whereas Spring Boot source code is JDK17 source compatible, hence either reflection or multi-release jar should be used to add support for VirtualThreadMetrics
.
I've prototyped changes in my branch by using reflection and FactoryBean
.
I also checked VirtualThreadMetrics
with a native-image, and unfortunately, I got the following exception:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'virtualThreadMetrics': Instantiation of supplied bean failed
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainFromSupplier(AbstractAutowireCapableBeanFactory.java:1239)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1176)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:563)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:523)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:336)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:288)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:334)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.instantiateSingleton(DefaultListableBeanFactory.java:1122)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingleton(DefaultListableBeanFactory.java:1093)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:1030)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:987)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:627)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:318)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1361)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1350)
at task.gh43122.Gh43122Application.main(Gh43122Application.java:12)
at java.base@21.0.5/java.lang.invoke.LambdaForm$DMH/sa346b79c.invokeStaticInit(LambdaForm$DMH)
Caused by: java.lang.UnsatisfiedLinkError: jdk.jfr.internal.JVM.getPid()Ljava/lang/String; [symbol: Java_jdk_jfr_internal_JVM_getPid or Java_jdk_jfr_internal_JVM_getPid__]
at org.graalvm.nativeimage.builder/com.oracle.svm.core.jni.access.JNINativeLinkage.getOrFindEntryPoint(JNINativeLinkage.java:152)
at org.graalvm.nativeimage.builder/com.oracle.svm.core.jni.JNIGeneratedMethodSupport.nativeCallAddress(JNIGeneratedMethodSupport.java:54)
at jdk.jfr@21.0.5/jdk.jfr.internal.JVM.getPid(Native Method)
at jdk.jfr@21.0.5/jdk.jfr.internal.Repository.createRepository(Repository.java:110)
at jdk.jfr@21.0.5/jdk.jfr.internal.Repository.setBasePath(Repository.java:65)
at jdk.jfr@21.0.5/jdk.jfr.internal.Repository.ensureRepository(Repository.java:79)
at jdk.jfr@21.0.5/jdk.jfr.internal.PlatformRecorder.<init>(PlatformRecorder.java:81)
at jdk.jfr@21.0.5/jdk.jfr.FlightRecorder.getFlightRecorder(FlightRecorder.java:171)
at jdk.jfr@21.0.5/jdk.jfr.Recording.<init>(Recording.java:107)
at jdk.jfr@21.0.5/jdk.jfr.Recording.<init>(Recording.java:131)
at jdk.jfr@21.0.5/jdk.jfr.consumer.RecordingStream.<init>(RecordingStream.java:108)
at jdk.jfr@21.0.5/jdk.jfr.consumer.RecordingStream.<init>(RecordingStream.java:101)
at io.micrometer.java21.instrument.binder.jdk.VirtualThreadMetrics.createRecordingStream(VirtualThreadMetrics.java:78)
at io.micrometer.java21.instrument.binder.jdk.VirtualThreadMetrics.<init>(VirtualThreadMetrics.java:57)
at io.micrometer.java21.instrument.binder.jdk.VirtualThreadMetrics.<init>(VirtualThreadMetrics.java:49)
at task.gh43122.Gh43122Application.virtualThreadMetrics(Gh43122Application.java:17)
at task.gh43122.Gh43122Application$$SpringCGLIB$$0.CGLIB$virtualThreadMetrics$0(<generated>)
at task.gh43122.Gh43122Application$$SpringCGLIB$$FastClass$$1.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:258)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:348)
at task.gh43122.Gh43122Application$$SpringCGLIB$$0.virtualThreadMetrics(<generated>)
at task.gh43122.Gh43122Application__BeanDefinitions.lambda$getVirtualThreadMetricsInstanceSupplier$0(Gh43122Application__BeanDefinitions.java:32)
at org.springframework.util.function.ThrowingFunction.apply(ThrowingFunction.java:63)
at org.springframework.util.function.ThrowingFunction.apply(ThrowingFunction.java:51)
at org.springframework.beans.factory.aot.BeanInstanceSupplier.lambda$get$1(BeanInstanceSupplier.java:219)
at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:58)
at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:46)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiateWithFactoryMethod(SimpleInstantiationStrategy.java:88)
at org.springframework.beans.factory.aot.BeanInstanceSupplier.invokeBeanSupplier(BeanInstanceSupplier.java:256)
at org.springframework.beans.factory.aot.BeanInstanceSupplier.get(BeanInstanceSupplier.java:219)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.obtainInstanceFromSupplier(DefaultListableBeanFactory.java:979)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainFromSupplier(AbstractAutowireCapableBeanFactory.java:1233)
... 20 more
Sample to reproduce: gh-43122.zip
mvn clean spring-boot:build-image -Pnative
docker run -p 8080:8080 docker.io/library/gh-43122:0.0.1-SNAPSHOT
Hi it can be done with some conditions as we have here. But I'm not sure if that is the right way or preferable strategy for the java 21 support
Micrometer added a new MeterBinder for virtual thread metrics via https://github.com/micrometer-metrics/micrometer/pull/5067 - documentation is at https://docs.micrometer.io/micrometer/reference/reference/jvm.html#_java_21_metrics. It is in a new module
micrometer-java21
. It would be nice if Spring Boot has auto-configuration forVirtualThreadMetrics
.