部署到独立的Apache Tomcat Web服务器时,Spring Boot 2.1 Web应用程序无法正常工作

时间:2019-07-03 06:35:56

标签: spring-boot tomcat

我有一个传统项目转换为Spring Boot,它需要一个自定义侦听器来加载配置文件,该配置文件在控制器中被引用为静态全局变量,当我将自定义侦听器添加到ServletListenerRegistrationBean嵌入式tomcat。但是,当使用传统的war包部署项目时,自定义侦听器不起作用,并导致启动失败。
这是一个简化的演示https://github.com/xuande/spring-boot-demo

@RestController
public class ConfigController {

    private Map<String, Object> configMap = ScaComponentFactory.getComponent();

    @GetMapping("/properties/{key}")
    public Object getConfig(@PathVariable("key") String key) {
        return configMap.get(key);
    }
}
public class ScaContextListener implements ServletContextListener {
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("start listener ...");
        ScaComponentFactory.map = new HashMap<>();
        ScaComponentFactory.map.put("test", "this is a demo");
    }

    public void contextDestroyed(ServletContextEvent sce) {
        ScaComponentFactory.map.clear();
        ScaComponentFactory.map = null;
    }
}

public class ScaComponentFactory {

    protected static Map<String, String> map = null;

    public static String getComponent(String key) {
        return map.get(key);
    }

    public static Map<String, Object> getComponent() {
        return Collections.unmodifiableMap(map);
    }
}

主班

@SpringBootApplication
public class Application extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Application.class);
    }

    @Bean
    public ServletListenerRegistrationBean<?> scaListenerRegistrationBean() {
        ServletListenerRegistrationBean<ScaContextListener> registration = new ServletListenerRegistrationBean<ScaContextListener>();
        registration.setListener(new ScaContextListener());
        return registration;
    }

}

具有嵌入式tomcat效果很好


  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.3.RELEASE)

2019-07-03 17:25:20.465  INFO 379676 --- [           main] org.spring.demo.Application              : Starting Application on xuande00 with PID 379676 (G:\git\spring-boot-demo\target\classes started by xuande in G:\git\spring-boot-demo)
2019-07-03 17:25:20.465  INFO 379676 --- [           main] org.spring.demo.Application              : No active profile set, falling back to default profiles: default
2019-07-03 17:25:23.481  INFO 379676 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 5050 (http)
2019-07-03 17:25:23.568  INFO 379676 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2019-07-03 17:25:23.568  INFO 379676 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.16]
2019-07-03 17:25:23.584  INFO 379676 --- [           main] o.a.catalina.core.AprLifecycleListener   : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [C:\Program Files\Java\jdk1.8.0_144\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;C:/Program Files/Java/jdk1.8.0_111/bin/../jre/bin/server;C:/Program Files/Java/jdk1.8.0_111/bin/../jre/bin;C:/Program Files/Java/jdk1.8.0_111/bin/../jre/lib/amd64;D:\Program Files (x86)\NetSarang\Xshell 6\;d:\program files\graphicsmagick-1.3.30-q16;C:\Program Files\Java\jdk1.8.0_111\bin;C:\ProgramData\Oracle\Java\javapath;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Windows\CCM;C:\Program Files\nodejs\;C:\Program Files\Git\cmd;C:\Program Files (x86)\Pandoc\;D:\Program Files\apache-maven-3.5.2\bin;;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;D:\Program Files\Microsoft VS Code\bin;D:\Program Files\Redis\;C:\Users\xuande\AppData\Local\Microsoft\WindowsApps;C:\Users\xuande\AppData\Roaming\npm;C:\Program Files (x86)\Pandoc\;D:\Program Files\hadoop-2.7.4\bin;D:\Program Files\gradle-4.6\bin;;E:\eclipse-loushang;;.]
2019-07-03 17:25:24.006  INFO 379676 --- [           main] org.apache.jasper.servlet.TldScanner     : At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
2019-07-03 17:25:24.006  INFO 379676 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2019-07-03 17:25:24.006  INFO 379676 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 3447 ms
start listener ...
2019-07-03 17:25:24.428  INFO 379676 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2019-07-03 17:25:25.037  INFO 379676 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 5050 (http) with context path ''
2019-07-03 17:25:25.075  INFO 379676 --- [           main] org.spring.demo.Application              : Started Application in 5.512 seconds (JVM running for 6.3)

独立的tomcat无法正常工作


July 03, 2019 5:21:35 PM org.apache.catalina.startup.VersionLoggerListener log
Info: Server version:        Apache Tomcat/8.5.24
July 03, 2019 5:21:35 PM org.apache.catalina.startup.VersionLoggerListener log
Info: Server built:          Nov 27 2017 13:05:30 UTC
July 03, 2019 5:21:35 PM org.apache.catalina.startup.VersionLoggerListener log
Info: Server number:         8.5.24.0
July 03, 2019 5:21:35 PM org.apache.catalina.startup.VersionLoggerListener log
Info: OS Name:               Windows 10
July 03, 2019 5:21:35 PM org.apache.catalina.startup.VersionLoggerListener log
Info: OS Version:            10.0
July 03, 2019 5:21:35 PM org.apache.catalina.startup.VersionLoggerListener log
Info: Architecture:          amd64
July 03, 2019 5:21:35 PM org.apache.catalina.startup.VersionLoggerListener log
Info: Java Home:             C:\Program Files\Java\jdk1.8.0_144\jre
July 03, 2019 5:21:35 PM org.apache.catalina.startup.VersionLoggerListener log
Info: JVM Version:           1.8.0_144-b01
July 03, 2019 5:21:35 PM org.apache.catalina.startup.VersionLoggerListener log
Info: JVM Vendor:            Oracle Corporation
July 03, 2019 5:21:35 PM org.apache.catalina.startup.VersionLoggerListener log
Info: CATALINA_BASE:         G:\apache-tomcat-8.5.24
July 03, 2019 5:21:35 PM org.apache.catalina.startup.VersionLoggerListener log
Info: CATALINA_HOME:         G:\apache-tomcat-8.5.24
July 03, 2019 5:21:35 PM org.apache.catalina.startup.VersionLoggerListener log
Info: Command line argument: -agentlib:jdwp=transport=dt_socket,suspend=y,address=localhost:8783
July 03, 2019 5:21:35 PM org.apache.catalina.startup.VersionLoggerListener log
Info: Command line argument: -Dcatalina.base=G:\apache-tomcat-8.5.24
July 03, 2019 5:21:35 PM org.apache.catalina.startup.VersionLoggerListener log
Info: Command line argument: -Dcatalina.home=G:\apache-tomcat-8.5.24
July 03, 2019 5:21:35 PM org.apache.catalina.startup.VersionLoggerListener log
Info: Command line argument: -Dwtp.deploy=G:\apache-tomcat-8.5.24\wtpwebapps
July 03, 2019 5:21:35 PM org.apache.catalina.startup.VersionLoggerListener log
Info: Command line argument: -Djava.endorsed.dirs=G:\apache-tomcat-8.5.24\endorsed
July 03, 2019 5:21:35 PM org.apache.catalina.startup.VersionLoggerListener log
Info: Command line argument: -Dfile.encoding=UTF-8
July 03, 2019 5:21:35 PM org.apache.catalina.core.AprLifecycleListener lifecycleEvent
Info: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [C:\Program Files\Java\jdk1.8.0_144\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\Program Files\Java\jdk1.8.0_144\jre\bin;C:/Program Files/Java/jdk1.8.0_111/bin/../jre/bin/server;C:/Program Files/Java/jdk1.8.0_111/bin/../jre/bin;C:/Program Files/Java/jdk1.8.0_111/bin/../jre/lib/amd64;D:\Program Files (x86)\NetSarang\Xshell 6\;d:\program files\graphicsmagick-1.3.30-q16;C:\Program Files\Java\jdk1.8.0_111\bin;C:\ProgramData\Oracle\Java\javapath;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Windows\CCM;C:\Program Files\nodejs\;C:\Program Files\Git\cmd;C:\Program Files (x86)\Pandoc\;D:\Program Files\apache-maven-3.5.2\bin;;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;D:\Program Files\Microsoft VS Code\bin;D:\Program Files\Redis\;C:\Users\xuande\AppData\Local\Microsoft\WindowsApps;C:\Users\xuande\AppData\Roaming\npm;C:\Program Files (x86)\Pandoc\;D:\Program Files\hadoop-2.7.4\bin;D:\Program Files\gradle-4.6\bin;;E:\eclipse-loushang;;.]
July 03, 2019 5:21:35 PM org.apache.coyote.AbstractProtocol init
Info: Initializing ProtocolHandler ["http-nio-9080"]
July 03, 2019 5:21:36 PM org.apache.tomcat.util.net.NioSelectorPool getSharedSelector
Info: Using a shared selector for servlet write/read
July 03, 2019 5:21:36 PM org.apache.coyote.AbstractProtocol init
Info: Initializing ProtocolHandler ["ajp-nio-9019"]
July 03, 2019 5:21:36 PM org.apache.tomcat.util.net.NioSelectorPool getSharedSelector
Info: Using a shared selector for servlet write/read
July 03, 2019 5:21:36 PM org.apache.catalina.startup.Catalina load
Info: Initialization processed in 1660 ms
July 03, 2019 5:21:36 PM org.apache.catalina.core.StandardService startInternal
Info: Starting service [Catalina]
July 03, 2019 5:21:36 PM org.apache.catalina.core.StandardEngine startInternal
Info: Starting Servlet Engine: Apache Tomcat/8.5.24
July 03, 2019 5:21:42 PM org.apache.jasper.servlet.TldScanner scanJars
Info: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
July 03, 2019 5:21:43 PM org.apache.catalina.core.ApplicationContext log
Info: 2 Spring WebApplicationInitializers detected on classpath

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.3.RELEASE)

2019-07-03 17:21:44.556  INFO 398420 --- [ost-startStop-1] org.spring.demo.Application              : Starting Application on xuande00 with PID 398420 (G:\git\spring-boot-demo\target\demo\WEB-INF\classes started by xuande in E:\eclipse-loushang)
2019-07-03 17:21:44.556  INFO 398420 --- [ost-startStop-1] org.spring.demo.Application              : No active profile set, falling back to default profiles: default
2019-07-03 17:21:46.041  INFO 398420 --- [ost-startStop-1] o.a.c.c.C.[.[localhost].[/demo]          : Initializing Spring embedded WebApplicationContext
2019-07-03 17:21:46.056  INFO 398420 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1422 ms
2019-07-03 17:21:46.667  WARN 398420 --- [ost-startStop-1] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'configController' defined in file [G:\git\spring-boot-demo\target\demo\WEB-INF\classes\org\spring\demo\controller\ConfigController.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.spring.demo.controller.ConfigController]: Constructor threw exception; nested exception is java.lang.NullPointerException
2019-07-03 17:21:46.683  INFO 398420 --- [ost-startStop-1] ConditionEvaluationReportLoggingListener : 

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2019-07-03 17:21:46.699 ERROR 398420 --- [ost-startStop-1] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'configController' defined in file [G:\git\spring-boot-demo\target\demo\WEB-INF\classes\org\spring\demo\controller\ConfigController.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.spring.demo.controller.ConfigController]: Constructor threw exception; nested exception is java.lang.NullPointerException
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1287) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1181) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:849) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:142) ~[spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775) ~[spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) ~[spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:316) ~[spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.run(SpringBootServletInitializer.java:157) [spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:137) [spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:91) [spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:171) [spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5196) [catalina.jar:8.5.24]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [catalina.jar:8.5.24]
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1419) [catalina.jar:8.5.24]
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1409) [catalina.jar:8.5.24]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_144]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_144]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_144]
    at java.lang.Thread.run(Thread.java:748) [na:1.8.0_144]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.spring.demo.controller.ConfigController]: Constructor threw exception; nested exception is java.lang.NullPointerException
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:184) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:87) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1279) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    ... 26 common frames omitted
Caused by: java.lang.NullPointerException: null
    at java.util.Collections$UnmodifiableMap.<init>(Collections.java:1446) ~[na:1.8.0_144]
    at java.util.Collections.unmodifiableMap(Collections.java:1433) ~[na:1.8.0_144]
    at org.spring.demo.listener.ScaComponentFactory.getComponent(ScaComponentFactory.java:15) ~[classes/:na]
    at org.spring.demo.controller.ConfigController.<init>(ConfigController.java:13) ~[classes/:na]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_144]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_144]
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_144]
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_144]
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:172) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    ... 28 common frames omitted

1 个答案:

答案 0 :(得分:0)

@Configuration
public class ScaContextInitializer implements ServletContextInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        System.out.println("start listener ...");
        ScaComponentFactory.map = new HashMap<>();
        ScaComponentFactory.map.put("test", "this is a demo");
    }

}

使用ServletContextInitializer代替ServletContextListener,嵌入式tomcat和独立的tomcat都可以很好地工作