-
Notifications
You must be signed in to change notification settings - Fork 41.2k
Actuator is not working with Jersey starter #2025
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
Comments
The actuator HTTP endpoints are exposed via Spring MVC and we currently don't provide equivalents for Jersey. I'm not sure if you can easily mix Jersey and Spring MVC (@dsyer might know). |
It can be done, but IME you do have to provide your own @Bean
public FilterRegistrationBean jersey() {
final FilterRegistrationBean jersey = new FilterRegistrationBean();
jersey.setFilter(new ServletContainer(this.config));
jersey.setMatchAfter(true);
jersey.addInitParameter("com.sun.jersey.config.feature.FilterForwardOn404", "true");
final String managementContextPath = stripTrailingSlash(this.management.getContextPath());
if (managementContextPath.isEmpty()) {
throw new IllegalStateException("Management context path must be non-empty");
} else {
final String managementContextRegex = managementContextPath + "/.+";
jersey.addInitParameter("com.sun.jersey.config.property.WebPageContentRegex", managementContextRegex);
}
return jersey;
} Jersey 2 would be trivially similar, with slightly different init parameter names. Getting it working with |
@philwebb: if other starters cannot be used on top of spring-boot-starter-jersey, it doesn't make sense to provide support to another REST fwk Thx |
I don't understand what the problem is really. Jersey (1 or 2) can be installed as either a servlet or a filter, and if you map those to the same path as the Actuator endpoints, of course it's not going to work. You don't need a custom registration for Jersey 2 for vanilla use cases either (filter and servlet and custom paths are supported out of the box, and Jersey has a ton of options that are supported through |
@ouaibsky: One option is to set the @dsyer: I think it's a matter of the perhaps unrealistic expectation that one can add a dependency on |
@dsyer, I'm exactly in the situation describe by @celkins below. Just putting spring-boot-starter-actuator to a spring-boot-starter-jersey and expecting it should work out of the box But I understand now it's a bit more tricky (and has been designed first to work with Spring MVC) @celkins Meaning if I move out DispatcherServlet, request will be automatically handle by jerseyServlet ? For information the output when I start the example and doing some REST requests (in facto no more output if a request works or not) [INFO] Attaching agents: []
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.2.0.BUILD-SNAPSHOT)
2014-12-03 22:10:33.284 INFO 4190 --- [ main] org.icroco.haura.kra.KraMain : Starting KraMain on legolas with PID 4190 (/home/christophe/git/haura/haura-kra/target/classes started by christophe in /home/christophe/git/haura/haura-kra)
2014-12-03 22:10:33.352 INFO 4190 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@64485a47: startup date [Wed Dec 03 22:10:33 CET 2014]; root of context hierarchy
2014-12-03 22:10:34.351 INFO 4190 --- [ main] o.s.b.f.s.DefaultListableBeanFactory : Overriding bean definition for bean 'beanNameViewResolver': replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration; factoryMethodName=beanNameViewResolver; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter; factoryMethodName=beanNameViewResolver; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter.class]]
2014-12-03 22:10:35.125 INFO 4190 --- [ main] f.a.AutowiredAnnotationBeanPostProcessor : JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
2014-12-03 22:10:36.019 INFO 4190 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080/http
2014-12-03 22:10:36.454 INFO 4190 --- [ main] o.apache.catalina.core.StandardService : Starting service Tomcat
2014-12-03 22:10:36.456 INFO 4190 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.0.15
2014-12-03 22:10:36.594 INFO 4190 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2014-12-03 22:10:36.594 INFO 4190 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 3247 ms
2014-12-03 22:10:37.755 INFO 4190 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'metricFilter' to: [/*]
2014-12-03 22:10:37.756 INFO 4190 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
2014-12-03 22:10:37.756 INFO 4190 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'webRequestLoggingFilter' to: [/*]
2014-12-03 22:10:37.756 INFO 4190 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2014-12-03 22:10:37.757 INFO 4190 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'applicationContextIdFilter' to: [/*]
2014-12-03 22:10:37.757 INFO 4190 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
2014-12-03 22:10:37.757 INFO 4190 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean : Mapping servlet: 'jerseyServlet' to [/*]
2014-12-03 22:10:37.760 INFO 4190 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
2014-12-03 22:10:38.105 INFO 4190 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@64485a47: startup date [Wed Dec 03 22:10:33 CET 2014]; root of context hierarchy
2014-12-03 22:10:38.184 INFO 4190 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],methods=[],params=[],headers=[],consumes=[],produces=[text/html],custom=[]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest)
2014-12-03 22:10:38.184 INFO 4190 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2014-12-03 22:10:38.215 INFO 4190 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2014-12-03 22:10:38.215 INFO 4190 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2014-12-03 22:10:38.289 INFO 4190 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2014-12-03 22:10:38.773 INFO 4190 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/dump],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2014-12-03 22:10:38.775 INFO 4190 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/autoconfig],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2014-12-03 22:10:38.778 INFO 4190 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/env/{name:.*}],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EnvironmentMvcEndpoint.value(java.lang.String)
2014-12-03 22:10:38.778 INFO 4190 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/env],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2014-12-03 22:10:38.779 INFO 4190 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/mappings],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2014-12-03 22:10:38.781 INFO 4190 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/shutdown],methods=[POST],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.ShutdownMvcEndpoint.invoke()
2014-12-03 22:10:38.782 INFO 4190 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/health],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.HealthMvcEndpoint.invoke(java.security.Principal)
2014-12-03 22:10:38.782 INFO 4190 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/metrics/{name:.*}],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.MetricsMvcEndpoint.value(java.lang.String)
2014-12-03 22:10:38.783 INFO 4190 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/metrics],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2014-12-03 22:10:38.784 INFO 4190 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/configprops],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2014-12-03 22:10:38.785 INFO 4190 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/info],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2014-12-03 22:10:38.795 INFO 4190 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/beans],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2014-12-03 22:10:38.796 INFO 4190 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/trace],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2014-12-03 22:10:38.822 INFO 4190 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2014-12-03 22:10:38.850 INFO 4190 --- [ main] o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase 0
2014-12-03 22:10:39.147 INFO 4190 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080/http
2014-12-03 22:10:39.149 INFO 4190 --- [ main] org.icroco.haura.kra.KraMain : Started KraMain in 6.252 seconds (JVM running for 6.759)
|
@ouaibsky These lines indicate the crux of your problem:
Compare that to what happens when you override
With such a configuration, the actuator endpoints (as well as everything else handled by
|
Thx @celkins I confirm it works by adding a property server.servletPath. |
I was also caught by this one, i.e. expecting the actuator to work with boot-starter-jersey. This was after we already committed to Jersey, so going back to webmvc is not an option. So now, it seems we have to depend on both webmvc (for example, via boot-starter-web) and jersey 2 (via boot-starter-jersey), i.e. have two REST libraries, which imho is not nice.
Above, the /configprops URL is still reported although the one to use is /spring/configprops. Also, I don't really know if the /webjars/** is now /spring/webjars/**, the same for /error etc. What makes things very, very confusing is that it is not documented anywhere that the actuator depends on webmvc; what is more, the spring-boot-actuator/pom.xml says the dependency on webmvc is optional ( spring-boot/spring-boot-actuator/pom.xml Lines 145 to 149 in de95012
|
I think the misunderstanding comes from the fact that the "web" exposure is just one feature of the actuator. You can access to the same features via JMX endpoints for instance. That's why it's optional
Granted it's not super obvious but this page on "Monitoring and management over HTTP" starts with:
I'll add an explicit tip in that section. |
Add an explicit note about the need of Spring MVC for actuator HTTP endpoints. Also explicitly mention Jersey since it can be a source of confusion. See gh-2025
Now I understand why it's marked optional, I didn't know about the other options (JMX, shell), now I read the full docs and know better. As for the note you added - do you think it would be worth adding how both MVC and Jersey can be used together? It seems, even in this very issue, even the Boot core devs weren't sure if and how to make it work. |
I think we didn't try to make it work, indeed. You can always create a separate issue to ask for a sample. PR more than welcome. |
See 77.3 Actuator and Jersey. Can confirm that it works. |
I turn around by adding @ApplicationPath("/api") to my jersey config so dispatcher servlet map / |
This might help someone using Jersey with Spring Boot. If you are using Jersey with Spring Boot, actuator doesn't work default spring.jersey.application-path=/mytest-app OR server.servlet-path=/mytest-app Also make sure following properties are set. server.context-path=/mytest-app |
@anilkonduru Jersey actuator endpoints are supported in Spring Boot 2.0 |
@philwebb Are you saying that actuator endpoints work by default in Spring Boot 2.0? Because I'm not seeing that behavior. I'm still seeing Jersey overrun the actuator endpoints:
|
What makes you think the endpoints have been “overrun”? Note that Jersey doesn’t log any mappings at startup so their absence from the log doesn’t mean anything. |
@wilkinsona Navigating to |
There’s no sign in the log output that you’ve shared that Jersey’s filter or Servlet has been registered so it looks like a broader problem. I’d check for corrupted dependencies, that you have a |
@wilkinsona - Thanks! Ill start working down that path. |
@wilkinsona @adenix Hopefully this will help - https://github.com/jokerr/boot2-jersey-actuator
|
Thanks, @jokerr. Hopefully it will. @adenix That sample shows the actuator available at
|
If it does not, there is another sample here |
@wilkinsona This is just my personal opinion, I think a point of confusion is not seeing the actuator endpoints register in the start up logs. Through tinkering with the Jersey + Actuator combo I've found that not all the documented management properties work out of the box unless you make certain changes. For example, I added a
However when I also change the port then things start working a little different.
Appreciate all your hard work on this project! |
Yeah, I got it working a few days ago. Then I had an issue using |
That's a side-effect of using Jersey. Boot itself doesn't log any of the Actuator endpoint mappings. Spring MVC and Spring WebFlux both log mappings at info level by default, Jersey doesn't and I don't believe there's a way to switch it on. I've opened #12442 to consider adding some logging to Boot.
This is the expected behaviour.
In some ways that's what I'd expect. On one hand, your |
Reading this https://docs.spring.io/spring-boot/docs/2.1.6.RELEASE/reference/htmlsingle/#production-ready-customizing-management-server-context-path (Using 2.1.6.RELEASE)
I modified the configuration this way +server:
+ servlet:
+ context-path: /
spring.mvc.servlet.path: /static
spring:
jersey:
application-path: /
servlet:
load-on-startup: 1
management:
endpoint:
health.enabled: true
+ endpoints:
+ web:
+ base-path: /actuator
+ path-mapping.health: healthcheck However actuators keep showing up under
So either there's something missing on the documentation or they are some limitations to how actuator integrate when there's both spring mvc and jersey. Even switching the dispatcher servlet to -spring.mvc.servlet.path: /static
+spring.mvc.servlet.path: / |
@bric3 If you have both Jersey and Spring MVC on the classpath, Actuator has to pick one so Spring MVC will take precedence. If you believe that something is unclear or that there's an improvement that could be made somewhere please open a new issue and we will take a look. |
Hi @wilkinsona, I believe that both could be improved.
This last is actually interesting if one want to migrate one endpoint at a time from one technology to another. I will open the issue. Thanks a lot. |
Hi
I just cloned the starter-jersey sample then tried to add dependency spring-boot-starter-actuator.
Looks like any context mapped by actuator are working
The trouble is stdout looks fine, saying all endpoints are added, but when doing /health or /metrics .... nothing appears in a browser.
In fact it's a 404 error (displayed woth curl -i)
Looks like error page are not working as well.
I guess all this is due to Jersey but not able to do more troubleshooting.
Tested on 1.2.0-BUILD-SNAPSHOT
Christophe
The text was updated successfully, but these errors were encountered: