应用程序在第二次启动时没有环境属性启动两次
Application starting twice without environment properties on the second startup
我们的 Spring 引导应用程序启动了两次,但在第二次启动时没有设置环境。所以在第二次启动时,应用程序无法启动。我们需要从外部 tomcat 配置目录设置应用程序。为了使日志记录正常工作,我们进行了以下设置。
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.14.RELEASE</version>
<relativePath />
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<start-class>foo.bar.MyApplication</start-class>
<tomcat.version>8.0.32</tomcat.version>
</properties>
<dependencies>
<!-- Spring Boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!-- Environment -->
<dependency>
<groupId>com.ibm.db2.jcc</groupId>
<artifactId>db2jcc4</artifactId>
<version>10.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<!-- Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
主要-class
@SpringBootApplication
@EnableAspectJAutoProxy
public class MyApplication extends SpringBootServletInitializer {
private static final Logger LOG = LoggerFactory.getLogger(MyApplication.class);
public MyApplication() {
LOG.info(">>>>>>>>>>> Welcome to MyApplication");
}
@Override
protected SpringApplicationBuilder configure(final SpringApplicationBuilder builder) {
return configureApplication(builder);
}
public static void main(final String[] args) {
configureApplication(new SpringApplicationBuilder()).run(args);
}
private static SpringApplicationBuilder configureApplication(final SpringApplicationBuilder builder) {
return builder.sources(MyApplication.class);
}
@Bean
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public MyBean getMyBean() {
LOG.debug("Created request scoped MyBean.");
return new MyBean();
}
}
server.xml(精简)
<?xml version="1.0" encoding="UTF-8"?>
<Server port="${tomcat.shutdown.port}" shutdown="SHUTDOWN">
<Listener SSLEngine="on" className="org.apache.catalina.core.AprLifecycleListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Service name="Catalina">
<Connector connectionTimeout="20000" port="8081" protocol="HTTP/1.1"
redirectPort="${environment.https.redirect.port}" server="Apache" />
<Connector port="9080" protocol="AJP/1.3"
redirectPort="${environment.https.redirect.port}" />
<Engine defaultHost="localhost" jvmRoute="${servername}" name="Catalina">
<Host appBase="${tomcat.webapp.dir}" autoDeploy="true" deployOnStartup="true" name="localhost" unpackWARs="true"
xmlNamespaceAware="false" xmlValidation="false">
<Context docBase="my-app" path="/myapp" reloadable="true">
<Parameter name="spring.config.location" value="file:C:/tomcat/conf/" />
<Parameter name="spring.config.name" value="myapp" /> <!-- results in myapp.properties -->
<Parameter name="org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH" value="true" />
</Context>
</Host>
</Engine>
</Service>
</Server>
日志
Jul 16, 2018 10:17:14 AM org.apache.catalina.core.AprLifecycleListener lifecycleEvent
INFO: Loaded APR based Apache Tomcat Native library 1.2.4 using APR version 1.5.1.
Jul 16, 2018 10:17:14 AM org.apache.catalina.core.AprLifecycleListener lifecycleEvent
INFO: APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true].
Jul 16, 2018 10:17:15 AM org.apache.catalina.core.AprLifecycleListener initializeSSL
INFO: OpenSSL successfully initialized (OpenSSL 1.0.2e 3 Dec 2015)
Jul 16, 2018 10:17:15 AM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["http-apr-8081"]
Jul 16, 2018 10:17:15 AM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["ajp-apr-9080"]
Jul 16, 2018 10:17:15 AM org.apache.catalina.startup.Catalina load
INFO: Initialization processed in 1404 ms
Jul 16, 2018 10:17:15 AM org.apache.catalina.core.StandardService startInternal
INFO: Starting service Catalina
Jul 16, 2018 10:17:15 AM org.apache.catalina.core.StandardEngine startInternal
INFO: Starting Servlet Engine: Apache Tomcat/8.0.32
Jul 16, 2018 10:17:25 AM 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.
Jul 16, 2018 10:17:26 AM org.apache.catalina.core.ApplicationContext log
INFO: 2 Spring WebApplicationInitializers detected on classpath
. ____ _ __ _ _
/\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.5.14.RELEASE)
2018-07-16 10:17:27.316 INFO 4880 --- [ost-startStop-1] f.b.MyApplication : Starting MyApplication v1.0.2-SNAPSHOT on tomcat with PID 4880 (C:\tomcat\webapps\myapp\WEB-INF\classes started by admin in C:\Eclipse\eclipse-jee-oxygen-1a-win32-x86_64\eclipse)
2018-07-16 10:17:27,362 localhost-startStop-1 ERROR Unable to create directory C:\Eclipse\eclipse-jee-oxygen-1a-win32-x86_64\eclipse${sys:LOG_PATH}18-07
2018-07-16 10:17:27.362 DEBUG 4880 --- [ost-startStop-1] f.b.MyApplication : Running with Spring Boot v1.5.14.RELEASE, Spring v4.3.18.RELEASE
2018-07-16 10:17:27.378 INFO 4880 --- [ost-startStop-1] f.b.MyApplication : No active profile set, falling back to default profiles: default
2018-07-16 10:17:27.472 INFO 4880 --- [ost-startStop-1] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@f7cbaab2: startup date [Mon Jul 16 10:17:27 CEST 2018]; root of context hierarchy
2018-07-16 10:17:29.562 INFO 4880 --- [ost-startStop-1] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$ddbcd45] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-07-16 10:17:29.859 INFO 4880 --- [ost-startStop-1] o.a.c.c.C.[.[.[/myapp] : Initializing Spring embedded WebApplicationContext
2018-07-16 10:17:29.859 INFO 4880 --- [ost-startStop-1] o.s.w.c.ContextLoader : Root WebApplicationContext: initialization completed in 2387 ms
2018-07-16 10:17:30.483 INFO 4880 --- [ost-startStop-1] o.s.b.w.s.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
2018-07-16 10:17:30.483 INFO 4880 --- [ost-startStop-1] o.s.b.w.s.FilterRegistrationBean : Mapping filter: 'errorPageFilter' to: [/*]
2018-07-16 10:17:30.483 INFO 4880 --- [ost-startStop-1] o.s.b.w.s.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
2018-07-16 10:17:30.483 INFO 4880 --- [ost-startStop-1] o.s.b.w.s.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2018-07-16 10:17:30.483 INFO 4880 --- [ost-startStop-1] o.s.b.w.s.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2018-07-16 10:17:30.483 INFO 4880 --- [ost-startStop-1] o.s.b.w.s.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
com.ibm.net.SocketKeepAliveParameters
2018-07-16 10:17:39.501 INFO 4880 --- [ost-startStop-1] j.LocalContainerEntityManagerFactoryBean : Building JPA container EntityManagerFactory for persistence unit 'default'
2018-07-16 10:17:42.903 INFO 4880 --- [ost-startStop-1] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2018-07-16 10:17:42.919 INFO 4880 --- [ost-startStop-1] f.b.MyApplication : >>>>>>>>>>> Welcome to MyApplication
2018-07-16 10:17:44.714 INFO 4880 --- [ost-startStop-1] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@f7cbaab2: startup date [Mon Jul 16 10:17:27 CEST 2018]; root of context hierarchy
2018-07-16 10:17:44.917 INFO 4880 --- [ost-startStop-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/root],methods=[GET]}" [...]
2018-07-16 10:17:45.120 INFO 4880 --- [ost-startStop-1] o.s.w.s.h.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-07-16 10:17:45.120 INFO 4880 --- [ost-startStop-1] o.s.w.s.h.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-07-16 10:17:45.214 INFO 4880 --- [ost-startStop-1] o.s.w.s.h.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-07-16 10:17:45.651 INFO 4880 --- [ost-startStop-1] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2018-07-16 10:17:46.151 INFO 4880 --- [ost-startStop-1] f.b.MyApplication : Started MyApplication in 19.788 seconds (JVM running for 32.145)
2018-07-16 10:17:46.166 INFO 4880 --- [ost-startStop-1] o.a.c.s.HostConfig : Deploying web application directory C:\tomcat\webapps\myapp
2018-07-16 10:17:53.420 INFO 4880 --- [ost-startStop-1] o.a.j.s.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.
2018-07-16 10:17:53.718 INFO 4880 --- [ost-startStop-1] o.a.c.c.C.[.[.[/myapp] : 2 Spring WebApplicationInitializers detected on classpath
. ____ _ __ _ _
/\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.5.14.RELEASE)
2018-07-16 10:17:54.435 INFO 4880 --- [ost-startStop-1] f.b.MyApplication : Starting MyApplication v1.0.2-SNAPSHOT on tomcat with PID 4880 (C:\tomcat\webapps\myapp\WEB-INF\classes started by admin in C:\Eclipse\eclipse-jee-oxygen-1a-win32-x86_64\eclipse)
2018-07-16 10:17:54.451 INFO 4880 --- [ost-startStop-1] f.b.MyApplication : No active profile set, falling back to default profiles: default
2018-07-16 10:17:54.530 INFO 4880 --- [ost-startStop-1] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@8cc9db4a: startup date [Mon Jul 16 10:17:54 CEST 2018]; root of context hierarchy
2018-07-16 10:17:56.308 INFO 4880 --- [ost-startStop-1] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$95fdde] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-07-16 10:17:56.575 INFO 4880 --- [ost-startStop-1] o.a.c.c.C.[.[.[/myapp] : Initializing Spring embedded WebApplicationContext
2018-07-16 10:17:56.575 INFO 4880 --- [ost-startStop-1] o.s.w.c.ContextLoader : Root WebApplicationContext: initialization completed in 2045 ms
2018-07-16 10:17:57.136 INFO 4880 --- [ost-startStop-1] o.s.b.w.s.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
2018-07-16 10:17:57.136 INFO 4880 --- [ost-startStop-1] o.s.b.w.s.FilterRegistrationBean : Mapping filter: 'errorPageFilter' to: [/*]
2018-07-16 10:17:57.136 INFO 4880 --- [ost-startStop-1] o.s.b.w.s.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
2018-07-16 10:17:57.136 INFO 4880 --- [ost-startStop-1] o.s.b.w.s.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2018-07-16 10:17:57.136 INFO 4880 --- [ost-startStop-1] o.s.b.w.s.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2018-07-16 10:17:57.136 INFO 4880 --- [ost-startStop-1] o.s.b.w.s.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
2018-07-16 10:17:57.214 WARN 4880 --- [ost-startStop-1] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Tomcat.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.tomcat.jdbc.pool.DataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embedded database please put a supported one on the classpath. If you have database settings to be loaded from a particular profile you may need to active it (no profiles are currently active).
2018-07-16 10:17:57.230 INFO 4880 --- [ost-startStop-1] utoConfigurationReportLoggingInitializer :
Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2018-07-16 10:17:57.230 ERROR 4880 --- [ost-startStop-1] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Cannot determine embedded database driver class for database type NONE
Action:
If you want an embedded database please put a supported one on the classpath. If you have database settings to be loaded from a particular profile you may need to active it (no profiles are currently active).
错误原因
server.xml(spring.config.location
和 spring.config.name
)中作为上下文属性的配置设置在第二次启动时未被考虑在内。所以 Spring 引导应用程序没有 myapp.properties 可用,因此 spring-boot-starter-data-jpa 找不到任何数据源设置的配置并且初始化失败。
分析
我研究了有关在 classpath 上检测到的两个 WebApplicationInitializers 的日志条目。这不是此行为的原因。有两个 WebApplicationInitializer:
org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration.JerseyWebApplicationInitializer
foo.bar.MyApplication
Jersey-initializer 来自依赖项:spring-boot-autoconfigure-1.5.14.RELEASE.jar 以及关于它的代码:
// We need to switch *off* the Jersey WebApplicationInitializer because it
// will try and register a ContextLoaderListener which we don't need
servletContext.setInitParameter("contextConfigLocation", "<NONE>");
Jersey WebApplicationInitializer 基本上什么都不做,这不是此行为的原因。
所以我研究了这种行为的堆栈跟踪并得到以下结果:
在 org.springframework.web.SpringServletContainerInitializer.onStartup(Set<Class<?>>, ServletContext)
上设置断点
首次启动
SpringServletContainerInitializer.onStartup(Set<Class<?>>, ServletContext) line: 169
StandardContext.startInternal() line: 5244
StandardContext(LifecycleBase).start() line: 147
ContainerBase$StartChild.call() line: 1408
ContainerBase$StartChild.call() line: 1398
FutureTask<V>.run() line: 277
ThreadPoolExecutor.runWorker(ThreadPoolExecutor$Worker) line: 1153
ThreadPoolExecutor$Worker.run() line: 628
Thread.run() line: 785
第二次启动
SpringServletContainerInitializer.onStartup(Set<Class<?>>, ServletContext) line: 169
StandardContext.startInternal() line: 5244
StandardContext(LifecycleBase).start() line: 147
StandardHost(ContainerBase).addChildInternal(Container) line: 725
StandardHost(ContainerBase).addChild(Container) line: 701
StandardHost.addChild(Container) line: 717
HostConfig.deployDirectory(ContextName, File) line: 1091
HostConfig$DeployDirectory.run() line: 1830
Executors$RunnableAdapter<T>.call() line: 522
FutureTask<V>.run() line: 277
ThreadPoolExecutor.runWorker(ThreadPoolExecutor$Worker) line: 1153
ThreadPoolExecutor$Worker.run() line: 628
Thread.run() line: 785
根据第二个堆栈跟踪,tomcat - 出于某种原因 - 想要再次部署目录 /tomcat/webapps/myapp 而这次 server.xml 的上下文属性未被使用。
提示
我们使用 spring.config.location
而不是 @PropertySources
因为我们需要完全控制日志记录。 属性 资源加载可能为时已晚,根本没有选择。
非常感谢您的帮助。
我自己解决了这个问题。原因是 tomcat 服务器本身。配置错误。由于这不是标准 tomcat 安装(客户专业化),因此在此处解释解决方案意义不大。
您必须有两个子 class SpringBootServletInitializer。 class 之一可能缺少@Configuration。如果你想要 运行 两个实例,那么请确保你在 SpringBootServletInitializer 的两个子 classes 上都有 @Configuration。如果你想 运行 单实例然后删除第二个继承。
我们的 Spring 引导应用程序启动了两次,但在第二次启动时没有设置环境。所以在第二次启动时,应用程序无法启动。我们需要从外部 tomcat 配置目录设置应用程序。为了使日志记录正常工作,我们进行了以下设置。
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.14.RELEASE</version>
<relativePath />
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<start-class>foo.bar.MyApplication</start-class>
<tomcat.version>8.0.32</tomcat.version>
</properties>
<dependencies>
<!-- Spring Boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!-- Environment -->
<dependency>
<groupId>com.ibm.db2.jcc</groupId>
<artifactId>db2jcc4</artifactId>
<version>10.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<!-- Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
主要-class
@SpringBootApplication
@EnableAspectJAutoProxy
public class MyApplication extends SpringBootServletInitializer {
private static final Logger LOG = LoggerFactory.getLogger(MyApplication.class);
public MyApplication() {
LOG.info(">>>>>>>>>>> Welcome to MyApplication");
}
@Override
protected SpringApplicationBuilder configure(final SpringApplicationBuilder builder) {
return configureApplication(builder);
}
public static void main(final String[] args) {
configureApplication(new SpringApplicationBuilder()).run(args);
}
private static SpringApplicationBuilder configureApplication(final SpringApplicationBuilder builder) {
return builder.sources(MyApplication.class);
}
@Bean
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public MyBean getMyBean() {
LOG.debug("Created request scoped MyBean.");
return new MyBean();
}
}
server.xml(精简)
<?xml version="1.0" encoding="UTF-8"?>
<Server port="${tomcat.shutdown.port}" shutdown="SHUTDOWN">
<Listener SSLEngine="on" className="org.apache.catalina.core.AprLifecycleListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Service name="Catalina">
<Connector connectionTimeout="20000" port="8081" protocol="HTTP/1.1"
redirectPort="${environment.https.redirect.port}" server="Apache" />
<Connector port="9080" protocol="AJP/1.3"
redirectPort="${environment.https.redirect.port}" />
<Engine defaultHost="localhost" jvmRoute="${servername}" name="Catalina">
<Host appBase="${tomcat.webapp.dir}" autoDeploy="true" deployOnStartup="true" name="localhost" unpackWARs="true"
xmlNamespaceAware="false" xmlValidation="false">
<Context docBase="my-app" path="/myapp" reloadable="true">
<Parameter name="spring.config.location" value="file:C:/tomcat/conf/" />
<Parameter name="spring.config.name" value="myapp" /> <!-- results in myapp.properties -->
<Parameter name="org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH" value="true" />
</Context>
</Host>
</Engine>
</Service>
</Server>
日志
Jul 16, 2018 10:17:14 AM org.apache.catalina.core.AprLifecycleListener lifecycleEvent
INFO: Loaded APR based Apache Tomcat Native library 1.2.4 using APR version 1.5.1.
Jul 16, 2018 10:17:14 AM org.apache.catalina.core.AprLifecycleListener lifecycleEvent
INFO: APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true].
Jul 16, 2018 10:17:15 AM org.apache.catalina.core.AprLifecycleListener initializeSSL
INFO: OpenSSL successfully initialized (OpenSSL 1.0.2e 3 Dec 2015)
Jul 16, 2018 10:17:15 AM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["http-apr-8081"]
Jul 16, 2018 10:17:15 AM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["ajp-apr-9080"]
Jul 16, 2018 10:17:15 AM org.apache.catalina.startup.Catalina load
INFO: Initialization processed in 1404 ms
Jul 16, 2018 10:17:15 AM org.apache.catalina.core.StandardService startInternal
INFO: Starting service Catalina
Jul 16, 2018 10:17:15 AM org.apache.catalina.core.StandardEngine startInternal
INFO: Starting Servlet Engine: Apache Tomcat/8.0.32
Jul 16, 2018 10:17:25 AM 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.
Jul 16, 2018 10:17:26 AM org.apache.catalina.core.ApplicationContext log
INFO: 2 Spring WebApplicationInitializers detected on classpath
. ____ _ __ _ _
/\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.5.14.RELEASE)
2018-07-16 10:17:27.316 INFO 4880 --- [ost-startStop-1] f.b.MyApplication : Starting MyApplication v1.0.2-SNAPSHOT on tomcat with PID 4880 (C:\tomcat\webapps\myapp\WEB-INF\classes started by admin in C:\Eclipse\eclipse-jee-oxygen-1a-win32-x86_64\eclipse)
2018-07-16 10:17:27,362 localhost-startStop-1 ERROR Unable to create directory C:\Eclipse\eclipse-jee-oxygen-1a-win32-x86_64\eclipse${sys:LOG_PATH}18-07
2018-07-16 10:17:27.362 DEBUG 4880 --- [ost-startStop-1] f.b.MyApplication : Running with Spring Boot v1.5.14.RELEASE, Spring v4.3.18.RELEASE
2018-07-16 10:17:27.378 INFO 4880 --- [ost-startStop-1] f.b.MyApplication : No active profile set, falling back to default profiles: default
2018-07-16 10:17:27.472 INFO 4880 --- [ost-startStop-1] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@f7cbaab2: startup date [Mon Jul 16 10:17:27 CEST 2018]; root of context hierarchy
2018-07-16 10:17:29.562 INFO 4880 --- [ost-startStop-1] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$ddbcd45] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-07-16 10:17:29.859 INFO 4880 --- [ost-startStop-1] o.a.c.c.C.[.[.[/myapp] : Initializing Spring embedded WebApplicationContext
2018-07-16 10:17:29.859 INFO 4880 --- [ost-startStop-1] o.s.w.c.ContextLoader : Root WebApplicationContext: initialization completed in 2387 ms
2018-07-16 10:17:30.483 INFO 4880 --- [ost-startStop-1] o.s.b.w.s.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
2018-07-16 10:17:30.483 INFO 4880 --- [ost-startStop-1] o.s.b.w.s.FilterRegistrationBean : Mapping filter: 'errorPageFilter' to: [/*]
2018-07-16 10:17:30.483 INFO 4880 --- [ost-startStop-1] o.s.b.w.s.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
2018-07-16 10:17:30.483 INFO 4880 --- [ost-startStop-1] o.s.b.w.s.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2018-07-16 10:17:30.483 INFO 4880 --- [ost-startStop-1] o.s.b.w.s.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2018-07-16 10:17:30.483 INFO 4880 --- [ost-startStop-1] o.s.b.w.s.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
com.ibm.net.SocketKeepAliveParameters
2018-07-16 10:17:39.501 INFO 4880 --- [ost-startStop-1] j.LocalContainerEntityManagerFactoryBean : Building JPA container EntityManagerFactory for persistence unit 'default'
2018-07-16 10:17:42.903 INFO 4880 --- [ost-startStop-1] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2018-07-16 10:17:42.919 INFO 4880 --- [ost-startStop-1] f.b.MyApplication : >>>>>>>>>>> Welcome to MyApplication
2018-07-16 10:17:44.714 INFO 4880 --- [ost-startStop-1] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@f7cbaab2: startup date [Mon Jul 16 10:17:27 CEST 2018]; root of context hierarchy
2018-07-16 10:17:44.917 INFO 4880 --- [ost-startStop-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/root],methods=[GET]}" [...]
2018-07-16 10:17:45.120 INFO 4880 --- [ost-startStop-1] o.s.w.s.h.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-07-16 10:17:45.120 INFO 4880 --- [ost-startStop-1] o.s.w.s.h.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-07-16 10:17:45.214 INFO 4880 --- [ost-startStop-1] o.s.w.s.h.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-07-16 10:17:45.651 INFO 4880 --- [ost-startStop-1] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2018-07-16 10:17:46.151 INFO 4880 --- [ost-startStop-1] f.b.MyApplication : Started MyApplication in 19.788 seconds (JVM running for 32.145)
2018-07-16 10:17:46.166 INFO 4880 --- [ost-startStop-1] o.a.c.s.HostConfig : Deploying web application directory C:\tomcat\webapps\myapp
2018-07-16 10:17:53.420 INFO 4880 --- [ost-startStop-1] o.a.j.s.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.
2018-07-16 10:17:53.718 INFO 4880 --- [ost-startStop-1] o.a.c.c.C.[.[.[/myapp] : 2 Spring WebApplicationInitializers detected on classpath
. ____ _ __ _ _
/\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.5.14.RELEASE)
2018-07-16 10:17:54.435 INFO 4880 --- [ost-startStop-1] f.b.MyApplication : Starting MyApplication v1.0.2-SNAPSHOT on tomcat with PID 4880 (C:\tomcat\webapps\myapp\WEB-INF\classes started by admin in C:\Eclipse\eclipse-jee-oxygen-1a-win32-x86_64\eclipse)
2018-07-16 10:17:54.451 INFO 4880 --- [ost-startStop-1] f.b.MyApplication : No active profile set, falling back to default profiles: default
2018-07-16 10:17:54.530 INFO 4880 --- [ost-startStop-1] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@8cc9db4a: startup date [Mon Jul 16 10:17:54 CEST 2018]; root of context hierarchy
2018-07-16 10:17:56.308 INFO 4880 --- [ost-startStop-1] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$95fdde] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-07-16 10:17:56.575 INFO 4880 --- [ost-startStop-1] o.a.c.c.C.[.[.[/myapp] : Initializing Spring embedded WebApplicationContext
2018-07-16 10:17:56.575 INFO 4880 --- [ost-startStop-1] o.s.w.c.ContextLoader : Root WebApplicationContext: initialization completed in 2045 ms
2018-07-16 10:17:57.136 INFO 4880 --- [ost-startStop-1] o.s.b.w.s.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
2018-07-16 10:17:57.136 INFO 4880 --- [ost-startStop-1] o.s.b.w.s.FilterRegistrationBean : Mapping filter: 'errorPageFilter' to: [/*]
2018-07-16 10:17:57.136 INFO 4880 --- [ost-startStop-1] o.s.b.w.s.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
2018-07-16 10:17:57.136 INFO 4880 --- [ost-startStop-1] o.s.b.w.s.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2018-07-16 10:17:57.136 INFO 4880 --- [ost-startStop-1] o.s.b.w.s.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2018-07-16 10:17:57.136 INFO 4880 --- [ost-startStop-1] o.s.b.w.s.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
2018-07-16 10:17:57.214 WARN 4880 --- [ost-startStop-1] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Tomcat.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.tomcat.jdbc.pool.DataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embedded database please put a supported one on the classpath. If you have database settings to be loaded from a particular profile you may need to active it (no profiles are currently active).
2018-07-16 10:17:57.230 INFO 4880 --- [ost-startStop-1] utoConfigurationReportLoggingInitializer :
Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2018-07-16 10:17:57.230 ERROR 4880 --- [ost-startStop-1] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Cannot determine embedded database driver class for database type NONE
Action:
If you want an embedded database please put a supported one on the classpath. If you have database settings to be loaded from a particular profile you may need to active it (no profiles are currently active).
错误原因
server.xml(spring.config.location
和 spring.config.name
)中作为上下文属性的配置设置在第二次启动时未被考虑在内。所以 Spring 引导应用程序没有 myapp.properties 可用,因此 spring-boot-starter-data-jpa 找不到任何数据源设置的配置并且初始化失败。
分析
我研究了有关在 classpath 上检测到的两个 WebApplicationInitializers 的日志条目。这不是此行为的原因。有两个 WebApplicationInitializer:
org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration.JerseyWebApplicationInitializer
foo.bar.MyApplication
Jersey-initializer 来自依赖项:spring-boot-autoconfigure-1.5.14.RELEASE.jar 以及关于它的代码:
// We need to switch *off* the Jersey WebApplicationInitializer because it
// will try and register a ContextLoaderListener which we don't need
servletContext.setInitParameter("contextConfigLocation", "<NONE>");
Jersey WebApplicationInitializer 基本上什么都不做,这不是此行为的原因。
所以我研究了这种行为的堆栈跟踪并得到以下结果:
在 org.springframework.web.SpringServletContainerInitializer.onStartup(Set<Class<?>>, ServletContext)
首次启动
SpringServletContainerInitializer.onStartup(Set<Class<?>>, ServletContext) line: 169
StandardContext.startInternal() line: 5244
StandardContext(LifecycleBase).start() line: 147
ContainerBase$StartChild.call() line: 1408
ContainerBase$StartChild.call() line: 1398
FutureTask<V>.run() line: 277
ThreadPoolExecutor.runWorker(ThreadPoolExecutor$Worker) line: 1153
ThreadPoolExecutor$Worker.run() line: 628
Thread.run() line: 785
第二次启动
SpringServletContainerInitializer.onStartup(Set<Class<?>>, ServletContext) line: 169
StandardContext.startInternal() line: 5244
StandardContext(LifecycleBase).start() line: 147
StandardHost(ContainerBase).addChildInternal(Container) line: 725
StandardHost(ContainerBase).addChild(Container) line: 701
StandardHost.addChild(Container) line: 717
HostConfig.deployDirectory(ContextName, File) line: 1091
HostConfig$DeployDirectory.run() line: 1830
Executors$RunnableAdapter<T>.call() line: 522
FutureTask<V>.run() line: 277
ThreadPoolExecutor.runWorker(ThreadPoolExecutor$Worker) line: 1153
ThreadPoolExecutor$Worker.run() line: 628
Thread.run() line: 785
根据第二个堆栈跟踪,tomcat - 出于某种原因 - 想要再次部署目录 /tomcat/webapps/myapp 而这次 server.xml 的上下文属性未被使用。
提示
我们使用 spring.config.location
而不是 @PropertySources
因为我们需要完全控制日志记录。 属性 资源加载可能为时已晚,根本没有选择。
非常感谢您的帮助。
我自己解决了这个问题。原因是 tomcat 服务器本身。配置错误。由于这不是标准 tomcat 安装(客户专业化),因此在此处解释解决方案意义不大。
您必须有两个子 class SpringBootServletInitializer。 class 之一可能缺少@Configuration。如果你想要 运行 两个实例,那么请确保你在 SpringBootServletInitializer 的两个子 classes 上都有 @Configuration。如果你想 运行 单实例然后删除第二个继承。