Spring boot dev tools is unable to restart the server automatically. POM:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.4.4</version>
    <relativePath/>
    <!-- lookup parent from repository -->
</parent>
<properties>
    <java.version>1.8</java.version>
</properties>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <scope>runtime</scope>
    <optional>true</optional>
</dependency>
<dependency>
    <groupId>org.apache.axis</groupId>
    <artifactId>axis</artifactId>
    <version>1.4</version>
</dependency>

Error:

Illegal access: this web application instance has been stopped already. Could not load [META-INF/services/org.apache.axis.EngineConfigurationFactory]. The following stack trace is thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access.

StackTrace:


java.lang.IllegalStateException: Illegal access: this web application instance has been stopped already. Could not load [META-INF/services/org.apache.axis.EngineConfigurationFactory]. The following stack trace is thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access.
    at org.apache.catalina.loader.WebappClassLoaderBase.checkStateForResourceLoading(WebappClassLoaderBase.java:1384) [tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.apache.catalina.loader.WebappClassLoaderBase.getResource(WebappClassLoaderBase.java:1037) [tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.apache.commons.discovery.jdk.JDK12Hooks.getResources(JDK12Hooks.java:134) [commons-discovery-0.5.jar:0.5]
    at org.apache.commons.discovery.resource.DiscoverResources$1.getNextResources(DiscoverResources.java:124) [commons-discovery-0.5.jar:0.5]
    at org.apache.commons.discovery.resource.DiscoverResources$1.getNextResource(DiscoverResources.java:98) [commons-discovery-0.5.jar:0.5]
    at org.apache.commons.discovery.resource.DiscoverResources$1.hasNext(DiscoverResources.java:84) [commons-discovery-0.5.jar:0.5]
    at org.apache.commons.discovery.resource.names.DiscoverNamesInFile$1.getNextClassNames(DiscoverNamesInFile.java:226) [commons-discovery-0.5.jar:0.5]
    at org.apache.commons.discovery.resource.names.DiscoverNamesInFile$1.getNextClassName(DiscoverNamesInFile.java:209) [commons-discovery-0.5.jar:0.5]
    at org.apache.commons.discovery.resource.names.DiscoverNamesInFile$1.hasNext(DiscoverNamesInFile.java:196) [commons-discovery-0.5.jar:0.5]
    at org.apache.commons.discovery.resource.names.NameDiscoverers$1.getNextIterator(NameDiscoverers.java:122) [commons-discovery-0.5.jar:0.5]
    at org.apache.commons.discovery.resource.names.NameDiscoverers$1.hasNext(NameDiscoverers.java:105) [commons-discovery-0.5.jar:0.5]
    at org.apache.commons.discovery.resource.classes.ResourceClassDiscoverImpl$1.getNextResource(ResourceClassDiscoverImpl.java:116) [commons-discovery-0.5.jar:0.5]
    at org.apache.commons.discovery.resource.classes.ResourceClassDiscoverImpl$1.hasNext(ResourceClassDiscoverImpl.java:103) [commons-discovery-0.5.jar:0.5]
    at org.apache.axis.configuration.EngineConfigurationFactoryFinder$1.run(EngineConfigurationFactoryFinder.java:120) [axis-1.4.jar:na]
    at java.security.AccessController.doPrivileged(Native Method) [na:1.8.0_131]
    at org.apache.axis.configuration.EngineConfigurationFactoryFinder.newFactory(EngineConfigurationFactoryFinder.java:113) [axis-1.4.jar:na]
    at org.apache.axis.configuration.EngineConfigurationFactoryFinder.newFactory(EngineConfigurationFactoryFinder.java:160) [axis-1.4.jar:na]
    at org.apache.axis.client.Service.getEngineConfiguration(Service.java:813) [axis-1.4.jar:na]
    at org.apache.axis.client.Service.getAxisClient(Service.java:104) [axis-1.4.jar:na]
    at org.apache.axis.client.Service.<init>(Service.java:113) [axis-1.4.jar:na]
    at com.fedex.ws.ship.v26.ShipServiceLocator.<init>(ShipServiceLocator.java:12) [classes/:na]
    at com.foo.service.ShipService.processShipment(ShipService.java:69) [classes/:na]
    at com.foo.controller.ShipController.processShipping(ShipController.java:38) [classes/:na]
    at com.foo.controller.ShipController$$FastClassBySpringCGLIB$$3bcae4f4.invoke(<generated>) [classes/:na]
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) [spring-core-5.3.5.jar:5.3.5]
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:779) [spring-aop-5.3.5.jar:5.3.5]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) [spring-aop-5.3.5.jar:5.3.5]
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750) [spring-aop-5.3.5.jar:5.3.5]
    at org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:123) [spring-context-5.3.5.jar:5.3.5]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) [spring-aop-5.3.5.jar:5.3.5]
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750) [spring-aop-5.3.5.jar:5.3.5]
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:692) [spring-aop-5.3.5.jar:5.3.5]
    at com.foo.controller.ShipController$$EnhancerBySpringCGLIB$$291f6053.processShipping(<generated>) [classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_131]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_131]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_131]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_131]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:197) [spring-web-5.3.5.jar:5.3.5]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:141) [spring-web-5.3.5.jar:5.3.5]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) [spring-webmvc-5.3.5.jar:5.3.5]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894) [spring-webmvc-5.3.5.jar:5.3.5]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) [spring-webmvc-5.3.5.jar:5.3.5]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) [spring-webmvc-5.3.5.jar:5.3.5]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1060) [spring-webmvc-5.3.5.jar:5.3.5]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:962) [spring-webmvc-5.3.5.jar:5.3.5]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) [spring-webmvc-5.3.5.jar:5.3.5]
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) [spring-webmvc-5.3.5.jar:5.3.5]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:652) [tomcat-embed-core-9.0.44.jar:4.0.FR]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) [spring-webmvc-5.3.5.jar:5.3.5]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) [tomcat-embed-core-9.0.44.jar:4.0.FR]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) [tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) [tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) [tomcat-embed-websocket-9.0.44.jar:9.0.44]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) [tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) [tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.springframework.web.filter.ShallowEtagHeaderFilter.doFilterInternal(ShallowEtagHeaderFilter.java:106) [spring-web-5.3.5.jar:5.3.5]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.3.5.jar:5.3.5]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) [tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) [tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) [spring-web-5.3.5.jar:5.3.5]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.3.5.jar:5.3.5]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) [tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) [tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) [spring-web-5.3.5.jar:5.3.5]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.3.5.jar:5.3.5]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) [tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) [tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) [spring-web-5.3.5.jar:5.3.5]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.3.5.jar:5.3.5]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) [tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) [tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) [tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) [tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) [tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143) [tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) [tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) [tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374) [tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893) [tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1707) [tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.44.jar:9.0.44]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [na:1.8.0_131]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [na:1.8.0_131]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.44.jar:9.0.44]
    at java.lang.Thread.run(Unknown Source) [na:1.8.0_131]

Comment From: snicoll

@harikesh409 Axis 1.4 is 15 years old and the stacktrace that you've shared in an exception that's thrown by Axis so I am wondering what makes you think this is an issue in Spring Boot. Rather than a partial project setup in text, please share a small sample that reproduces the problem. You can do so by attaching a zip to this issue or sharing a link to a GitHub repository.

Comment From: harikesh409

@harikesh409 Axis 1.4 is 15 years old and the stacktrace that you've shared in an exception that's thrown by Axis so I am wondering what makes you think this is an issue in Spring Boot. Rather than a partial project setup in text, please share a small sample that reproduces the problem. You can do so by attaching a zip to this issue or sharing a link to a GitHub repository.

In the initial run the code is running fun but as soon as some changes are done and the devtools gets trigged then I am facing this issue, as devtools is causing it I am thinking that it is an issue with spring and not others.

The reason for using Axis 1.4 is we need to consume FedEx SOAP service and in their developer guide they mentioned to use that specific version.

Comment From: wilkinsona

Yeah, it could be a Spring-related problem, but we need your help to figure that out. If you would like us to spend some more time investigating then, as @snicoll requested above, please spend some time providing a complete yet minimal sample that reproduces the problem. You can share it with us by pushing it to a separate repository on GitHub or by zipping it up and attaching it to this issue.

Comment From: harikesh409

@wilkinsona @snicoll As requested here is a sample project. demo.zip

Steps To Reproduce:

  1. After initial run goto http://localhost:8080/hello
  2. Update some code in the project and let the spring dev tools restart the server.
  3. Again goto http://localhost:8080/hello then the error is thrown.

IDE Used: Eclipse Java Version: 1.8_131

Comment From: wilkinsona

Thanks for the sample.

The problem you're experiencing is due to a bug in Axis. The first time AxisProperties.getNameDiscoverer() is called, it performs lazy initialization of some static fields. As part of this initialization a reference to the thread context class loader is retrieved and stored in a static field. This will cause problems in any environment where the ClassLoader of AxisProperties and the thread context class loader are not the same. For example, if you deployed an application to a servlet container with Axis configured as a shared library, the shared library would capture a reference to the web app class loader of the first web application to call AxisProperties.getNameDiscoverer(). Undeploying that web application would then result in a memory leak as its ClassLoader could not be garbage collected. A similar problem occurs with Devtools where a new web app class loader is created for each restart, but Axis holds onto the web app class loader from the first time it's called.

You can avoid the problem by getting Axis to initialise its name discoverer outside of a web request. This prevents it from capturing a reference to the web app class loader. To do so, add the following method to your main application class:

@PostConstruct
void preventAxisPropertiesClassLoaderLeak() {
    ClassLoader tccl = Thread.currentThread().getContextClassLoader();
    Thread.currentThread().setContextClassLoader(AxisProperties.class.getClassLoader());
    AxisProperties.getNameDiscoverer();
    Thread.currentThread().setContextClassLoader(tccl);
}

An alternative approach would be to use reflection to set AxisProperties' loader and nameDiscoverer fields to null, however the approach above appears to be sufficient and feels slightly simpler to me.

Comment From: harikesh409

Thanks for the sample.

The problem you're experiencing is due to a bug in Axis. The first time AxisProperties.getNameDiscoverer() is called, it performs lazy initialization of some static fields. As part of this initialization a reference to the thread context class loader is retrieved and stored in a static field. This will cause problems in any environment where the ClassLoader of AxisProperties and the thread context class loader are not the same. For example, if you deployed an application to a servlet container with Axis configured as a shared library, the shared library would capture a reference to the web app class loader of the first web application to call AxisProperties.getNameDiscoverer(). Undeploying that web application would then result in a memory leak as its ClassLoader could not be garbage collected. A similar problem occurs with Devtools where a new web app class loader is created for each restart, but Axis holds onto the web app class loader from the first time it's called.

You can avoid the problem by getting Axis to initialise its name discoverer outside of a web request. This prevents it from capturing a reference to the web app class loader. To do so, add the following method to your main application class:

java @PostConstruct void preventAxisPropertiesClassLoaderLeak() { ClassLoader tccl = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(AxisProperties.class.getClassLoader()); AxisProperties.getNameDiscoverer(); Thread.currentThread().setContextClassLoader(tccl); }

An alternative approach would be to use reflection to set AxisProperties' loader and nameDiscoverer fields to null, however the approach above appears to be sufficient and feels slightly simpler to me.

Thank you I was able to resolve using the given snippet.

Comment From: Pedasoft-Consult

  | "Illegal access: this web application instance has been stopped already. Could not load [org/springframework/cloud/loadbalancer/annotation/LoadBalancerClientConfiguration$ReactiveSupportConfiguration.class]. The following stack trace is thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access." -- | --