java.lang.NoClassDefFoundError: javax/servlet/ServletContext APM agent 1.29.0 in Docker

I am running Tomcat 9.0.52 in K8s from the Docker tomcat:9.0.52-jdk11-corretto image. I've downloaded the agent from https://repo1.maven.org/maven2/co/elastic/apm/elastic-apm-agent/1.29.0/elastic-apm-agent-1.29.0.jar and added the following CATALINA_OPTS env variable:

            -javaagent:/usr/local/tomcat/elastic-apm-agent-1.29.0.jar
            -Delastic.apm.service_name=myapp
            -Delastic.apm.application_packages=com.myco
            -Delastic.apm.server_url=http://apm-server-apm-server.default.svc.cluster.local:8200
            -Delastic.apm.environment=mynamespace

All applications running with this image have the following in their tomcat log at startup:

java.lang.NoClassDefFoundError: javax/servlet/ServletContext
	at co.elastic.apm.agent.servlet.adapter.JavaxServletApiAdapter.getServletContextName(JavaxServletApiAdapter.java:42)
	at co.elastic.apm.agent.servlet.ServletServiceNameHelper.detectServiceInfo(ServletServiceNameHelper.java:58)
	at co.elastic.apm.agent.springwebmvc.SpringServiceNameInstrumentation$SpringServiceNameAdvice.afterInitPropertySources(SpringServiceNameInstrumentation.java:90)
	at org.springframework.web.context.support.AbstractRefreshableWebApplicationContext.initPropertySources(AbstractRefreshableWebApplicationContext.java:214)
	at org.springframework.context.support.AbstractApplicationContext.prepareRefresh(AbstractApplicationContext.java:634)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)
	at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:702)
	at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:668)
	at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:716)
	at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:591)
	at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:530)
	at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:170)
	at javax.servlet.GenericServlet.init(GenericServlet.java:158)
	at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1143)
	at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1096)
	at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:989)
	at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4957)
	at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5264)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
	at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:726)
	at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:698)
	at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:696)
	at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1024)
	at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1911)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
	at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:118)
	at org.apache.catalina.startup.HostConfig.deployWARs(HostConfig.java:825)
	at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:475)
	at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1618)
	at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:319)
	at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:123)
	at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:423)
	at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:366)
	at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:946)
	at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:835)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1396)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1386)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
	at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:140)
	at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:919)
	at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:263)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
	at org.apache.catalina.core.StandardService.startInternal(StandardService.java:432)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
	at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:927)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
	at org.apache.catalina.startup.Catalina.start(Catalina.java:772)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:345)
	at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:476)
Caused by: java.lang.ClassNotFoundException: javax.servlet.ServletContext
	at co.elastic.apm.agent.premain.ShadedClassLoader.findClass(ShadedClassLoader.java:77)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:589)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
	... 50 more

This doesn't seem to affect the application or the APM agent, not sure if this is a real issue or if something is misconfigured?

Hi @jseletz , thanks for reporting this.

I have managed to reproduce it, thus I will open an issue and investigate it further, I'll update this discussion when I have links to issue/PR to share.

In the mean time, you can disable the instrumentation that triggers it by setting
disable_instrumentations=spring-service-name (doc). The downside of this issue is that the agent won't be able to automatically use the application name set in Spring configuration and you will have to add an explicit service_name configuration for your application.

2 Likes

Hi @jseletz , the issue should be fixed with this PR.

In order to make sure it now works as expected in your application, could you try with this snapshot and tell us if it works as expected in your case ?

Hi Sylvain, we have an application running in pivotal cloud foundry with the same issue. I've opened a support case to get visibility on this.

Can you please discuss what exactly is set using spring-service-name? Is this what is set in service.name or something specific to spring? Can you share in the ECS or APM data where/how this field is used and stored? I need to understand the impact. And you state to add explicit service_name so I'd like to understand how that is accomplished as well.

Thank you!

Hi - your workaround is fine as we already needed to set the service_name. I don't have an easy way to test with your patch since we've deployed all our apps with your suggested configuration.

Thanks for the confirmation @jseletz , the PR has been approved and will be merged soon (and included in the next release, if you haven't already make sure to subscribe to release notifications).

@jonahzirkle : the instrumentation of spring context startup allows the agent to automatically set the service_name configuration from the spring.application.name property in Spring context.
Until the next release is available you should be able to use the work-around. Once the 1.30.0 version is available the work-around won't be necessary.

This topic was automatically closed 20 days after the last reply. New replies are no longer allowed.