Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using Counter from io.micrometer:micrometer-registry-prometheus causes error in the application #41136

Closed
mauriciogeneroso opened this issue Jun 17, 2024 · 2 comments
Labels
for: external-project For an external project and not something we can fix status: invalid An issue that we don't feel is valid

Comments

@mauriciogeneroso
Copy link

mauriciogeneroso commented Jun 17, 2024

Context

After the upgrade to Spring 3.3.+, when starting a project that contains the library io.micrometer:micrometer-registry-prometheus, and we use Counter, it couses the error on runtime:

Stack Trace
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler dispatch failed: java.lang.NoClassDefFoundError: io/prometheus/metrics/tracer/initializer/SpanContextSupplier] with root cause

java.lang.ClassNotFoundException: io.prometheus.metrics.tracer.initializer.SpanContextSupplier
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) ~[na:na]
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) ~[na:na]
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520) ~[na:na]
	at io.prometheus.metrics.core.exemplars.ExemplarSampler.doSampleExemplar(ExemplarSampler.java:327) ~[prometheus-metrics-core-1.2.1.jar:na]
	at io.prometheus.metrics.core.exemplars.ExemplarSampler.updateExemplar(ExemplarSampler.java:310) ~[prometheus-metrics-core-1.2.1.jar:na]
	at io.prometheus.metrics.core.exemplars.ExemplarSampler.doObserveSingleExemplar(ExemplarSampler.java:123) ~[prometheus-metrics-core-1.2.1.jar:na]
	at io.prometheus.metrics.core.exemplars.ExemplarSampler.doObserve(ExemplarSampler.java:111) ~[prometheus-metrics-core-1.2.1.jar:na]
	at io.prometheus.metrics.core.exemplars.ExemplarSampler.lambda$observe$0(ExemplarSampler.java:99) ~[prometheus-metrics-core-1.2.1.jar:na]
	at io.prometheus.metrics.core.exemplars.ExemplarSampler.rateLimitedObserve(ExemplarSampler.java:276) ~[prometheus-metrics-core-1.2.1.jar:na]
	at io.prometheus.metrics.core.exemplars.ExemplarSampler.observe(ExemplarSampler.java:99) ~[prometheus-metrics-core-1.2.1.jar:na]
	at io.prometheus.metrics.core.metrics.Counter$DataPoint.inc(Counter.java:167) ~[prometheus-metrics-core-1.2.1.jar:na]
	at io.prometheus.metrics.core.metrics.Counter.inc(Counter.java:53) ~[prometheus-metrics-core-1.2.1.jar:na]
	at io.prometheus.metrics.core.datapoints.CounterDataPoint.inc(CounterDataPoint.java:53) ~[prometheus-metrics-core-1.2.1.jar:na]
	at com.example.demo.ControllerTest.test(ControllerTest.java:21) ~[main/:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:255) ~[spring-web-6.1.8.jar:6.1.8]
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:188) ~[spring-web-6.1.8.jar:6.1.8]
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) ~[spring-webmvc-6.1.8.jar:6.1.8]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:926) ~[spring-webmvc-6.1.8.jar:6.1.8]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:831) ~[spring-webmvc-6.1.8.jar:6.1.8]
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-6.1.8.jar:6.1.8]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089) ~[spring-webmvc-6.1.8.jar:6.1.8]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979) ~[spring-webmvc-6.1.8.jar:6.1.8]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) ~[spring-webmvc-6.1.8.jar:6.1.8]
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903) ~[spring-webmvc-6.1.8.jar:6.1.8]
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) ~[tomcat-embed-core-10.1.24.jar:6.0]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.1.8.jar:6.1.8]
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) ~[tomcat-embed-core-10.1.24.jar:6.0]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195) ~[tomcat-embed-core-10.1.24.jar:10.1.24]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.24.jar:10.1.24]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) ~[tomcat-embed-websocket-10.1.24.jar:10.1.24]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.24.jar:10.1.24]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.24.jar:10.1.24]
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.1.8.jar:6.1.8]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.8.jar:6.1.8]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.24.jar:10.1.24]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.24.jar:10.1.24]
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.1.8.jar:6.1.8]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.8.jar:6.1.8]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.24.jar:10.1.24]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.24.jar:10.1.24]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.1.8.jar:6.1.8]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.8.jar:6.1.8]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.24.jar:10.1.24]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.24.jar:10.1.24]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) ~[tomcat-embed-core-10.1.24.jar:10.1.24]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) ~[tomcat-embed-core-10.1.24.jar:10.1.24]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) ~[tomcat-embed-core-10.1.24.jar:10.1.24]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) ~[tomcat-embed-core-10.1.24.jar:10.1.24]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat-embed-core-10.1.24.jar:10.1.24]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-10.1.24.jar:10.1.24]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) ~[tomcat-embed-core-10.1.24.jar:10.1.24]
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:389) ~[tomcat-embed-core-10.1.24.jar:10.1.24]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-embed-core-10.1.24.jar:10.1.24]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:896) ~[tomcat-embed-core-10.1.24.jar:10.1.24]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1741) ~[tomcat-embed-core-10.1.24.jar:10.1.24]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.24.jar:10.1.24]
	at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190) ~[tomcat-embed-core-10.1.24.jar:10.1.24]
	at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.24.jar:10.1.24]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) ~[tomcat-embed-core-10.1.24.jar:10.1.24]
	at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]

How to reproduce the error?

  1. Start a new Spring boot application (it might be from https://start.spring.io/)
  2. Includes the dependencies web and prometheus
  3. Change the library 'io.micrometer:micrometer-registry-prometheus' to be implementation and not runtimeOnly
  4. In the code, create a controller that contains a Counter like this one:
Controller
@RestController
@RequestMapping("/test")
public class ControllerTest {


    @GetMapping
    public String test() {
        Counter counter = Counter.builder()
            .name("test_metric")
            .build();

        counter.inc();
        return "test";
    }

}

--> Download a demo project:
demo.zip

  1. Start the application, and call http://localhost:8080/test
  2. The error will happen

Alternatives

The alternatives found to fix the issue, is setting the Counter without Examples (method .withoutExemplars()), or import the library io.prometheus:metrics.tracer.initializer explicitly.

Notes

During investigation, found that the issue started with the change in the java_client 1.x on this commit

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Jun 17, 2024
@wilkinsona
Copy link
Member

wilkinsona commented Jun 17, 2024

Thanks for the report but this is out of Spring Boot's control. With a dependency on io.micrometer:micrometer-registry-prometheus:1.13.0 (and no Spring Boot dependencies), the following will fail in the way that you have described:

package com.example.gh_41136;

import io.prometheus.metrics.core.metrics.Counter;

public class Gh41136Application {

	public static void main(String[] args) {
		Counter.builder().name("test_metric").build().inc();
	}

}

Interestingly, the problem does not occur with a dependency on only io.prometheus:prometheus-metrics-core:1.2.1 so the failure appears to be related to the combination of dependencies that are pulled in through micrometer-registry-prometheus. Please open a Micrometer issue so that they can investigate.

@wilkinsona wilkinsona closed this as not planned Won't fix, can't repro, duplicate, stale Jun 17, 2024
@wilkinsona wilkinsona added status: invalid An issue that we don't feel is valid for: external-project For an external project and not something we can fix and removed status: waiting-for-triage An issue we've not yet triaged labels Jun 17, 2024
@mauriciogeneroso
Copy link
Author

Thank you @wilkinsona . Reported: micrometer-metrics/micrometer#5225

@philwebb philwebb changed the title [Spring boot 3.3.+] Using Counter from io.micrometer:micrometer-registry-prometheus causes error in the application Using Counter from io.micrometer:micrometer-registry-prometheus causes error in the application Jun 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
for: external-project For an external project and not something we can fix status: invalid An issue that we don't feel is valid
Projects
None yet
Development

No branches or pull requests

3 participants