ApplicationListener 处理 ContextClosedEvent 的 NullPointer 警告

Cal*_*ney 4 java spring cxf spring-boot

我有一个 Spring Boot Apache CXF Web 应用程序。它运行得很好。但是,每当我关闭应用程序时,我都会收到有关处理 ContextClosedEvent 的 ApplicationListener 的空指针的警告。看起来它可能与 Apache CXF 总线有关。

11:10:24.728 INFO  [Thread-10][AnnotationConfigEmbeddedWebApplicationContext] Closing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@39b667c3: startup date [Thu May 11 11:09:48 PDT 2017]; root of context hierarchy
11:10:24.738 WARN  [Thread-10][AnnotationConfigEmbeddedWebApplicationContext] Exception thrown from ApplicationListener handling ContextClosedEvent
java.lang.NullPointerException: null
    at java.util.concurrent.ConcurrentHashMap.replaceNode(ConcurrentHashMap.java:1106)
    at java.util.concurrent.ConcurrentHashMap.remove(ConcurrentHashMap.java:1097)
    at org.apache.cxf.transport.http.DestinationRegistryImpl.removeDestination(DestinationRegistryImpl.java:63)
    at org.apache.cxf.transport.http.AbstractHTTPDestination.deactivate(AbstractHTTPDestination.java:961)
    at org.apache.cxf.transport.AbstractObservable.setMessageObserver(AbstractObservable.java:65)
    at org.apache.cxf.endpoint.ServerImpl.stop(ServerImpl.java:174)
    at org.apache.cxf.endpoint.ServerImpl.destroy(ServerImpl.java:180)
    at org.apache.cxf.bus.managers.ServerRegistryImpl.preShutdown(ServerRegistryImpl.java:90)
    at org.apache.cxf.bus.managers.CXFBusLifeCycleManager.preShutdown(CXFBusLifeCycleManager.java:97)
    at org.apache.cxf.bus.extension.ExtensionManagerBus.shutdown(ExtensionManagerBus.java:326)
    at org.apache.cxf.bus.extension.ExtensionManagerBus.shutdown(ExtensionManagerBus.java:313)
    at org.apache.cxf.bus.spring.SpringBus.onApplicationEvent(SpringBus.java:109)
    at org.apache.cxf.bus.spring.SpringBus$1.onApplicationEvent(SpringBus.java:58)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:166)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:138)
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:382)
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:336)
    at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:989)
    at org.springframework.context.support.AbstractApplicationContext$2.run(AbstractApplicationContext.java:923)
11:10:24.780 INFO  [Thread-10][AnnotationMBeanExporter] Unregistering JMX-exposed beans on shutdown
Run Code Online (Sandbox Code Playgroud)

这是我写的一个类,我认为错误可能源于此,但我不确定。

import javax.xml.ws.Endpoint;
import org.apache.cxf.Bus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;


@Configuration
public class EndpointConfig {

    @Autowired
    private Bus bus;

    @Autowired
    private AmazonS3 s3client;

    @Bean
    public Endpoint endpoint() {
      EndpointImpl endpoint = new EndpointImpl(bus,
            new AcmeWebServiceImpl(s3client));
      endpoint.publish();
      return endpoint;
  }

  @Bean 
  public AmazonS3 amazonS3(){
     AmazonS3 amazonS3 = AmazonS3ClientBuilder.defaultClient();
     return amazonS3;
  }
}
Run Code Online (Sandbox Code Playgroud)

Cre*_*a S 5

我将其发布为答案,也许对其他人也有帮助。

\n\n

是的,我确实设法修复它 \xe2\x80\xa6 经过 3 天的尝试 \xe2\x80\xa6 it\xe2\x80\x99s 更像是一个解决方法,也许修复说得太多了,因为修复应该是可能是在cxf代码\xe2\x80\xa6中完成的实际上我们的堆栈跟踪有点不同,我将其附加在下面。在某种程度上类似,所以也许我们修复它的方法会对您有所帮助。这里是:

\n\n

在此输入图像描述

\n\n

我们注意到,在DestinationRegistryImpl -removeDestination方法中,第 63 行,从ConcurrentHashmap中删除的路径为 null,并且该路径来自上一级AbstractHTTPDestination.deactivate(AbstractHTTPDestination.java:965)在我们的例子中,我们使用了ServletDestination的实例( AbstractHTTPDestination的子级),它继承了 protected 变量路径,并通过 org.apache.cxf.transport.servlet.ServletDestinationFactory - #33 中的构造函数(ServletDestination 构造函数)设置了该变量,其中EndpointInfo 实例的地址被设置为路径。\n我们所要做的就是为我们的端点(JAXRSServerFactoryBean)设置一个地址,这意味着路径不再为空,并且我们摆脱了 NPE。

\n\n

我对它的长度感到抱歉,希望它有意义\xe2\x80\xa6我们花了整整 3 天的时间调试并查看 cxf 框架的代码,这不是很好。

\n\n

我们添加了第 74 行并去掉了 NPE:

\n\n

在此输入图像描述

\n