从 Spring Boot 1.3.3 -> 1.3.5 升级时,嵌入式 tomcat 无法启动
Embedded tomcat fails to start when upgraded from Spring Boot 1.3.3 -> 1.3.5
Spring 从 1.3.3 升级到 1.3.5 后启动应用程序无法启动。
Spring 无法启动嵌入式容器 (Tomcat 8) 并显示以下错误消息:
org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'embeddedServletContainerFactory': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [wad.config.HttpsConfiguration]: No default constructor found; nested exception is java.lang.NoSuchMethodException: wad.config.HttpsConfiguration.()
基本上这个错误消息说它不能创建 embeddedServletContainerFactory
,但我不清楚 [wad.config.HttpsConfiguration]
指的是什么。 Java 配置 class 本身在包 wad.config
中并命名为 HttpsConfiguration
。
我试图将空构造函数添加到我的 HttpsConfiguration.java
但它没有帮助。
以下是我的 POM 的相关部分:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.5.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
...
</dependencies>
我的申请class:
@EntityScan(
basePackageClasses = {Application.class, Jsr310JpaConverters.class}
)
@SpringBootApplication
@Import({DevProfile.class})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
这是我的端口重定向配置,从 8080 -> 8443(可通过 application.properties 配置):
@Configuration
public class HttpsConfiguration {
@Value("${server.port}")
private int httpsPort;
@Value("${server.port.http}")
private int httpPort;
@Bean
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory() {
@Override
protected void postProcessContext(Context context) {
SecurityConstraint securityConstraint = new SecurityConstraint();
securityConstraint.setUserConstraint("CONFIDENTIAL");
SecurityCollection collection = new SecurityCollection();
collection.addPattern("/*");
securityConstraint.addCollection(collection);
context.addConstraint(securityConstraint);
}
};
tomcat.addAdditionalTomcatConnectors(initiateHttpConnector());
return tomcat;
}
// redirect from (http) port to (https) if https is enabled.
private Connector initiateHttpConnector() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setScheme("http");
connector.setPort(httpPort);
connector.setSecure(false);
connector.setRedirectPort(httpsPort);
return connector;
}
application.properties 配置:
...
#Actuator port
management.port = 9001
#HTTPS port
server.port=8443
#HTTP port
server.port.http=8080
#Enable SSL
server.ssl.enabled=true
...
更新:
问题可以通过 Spring 配置有上述 POM、application.properties 和 HttpSecurity & Application classes 的 Boot 1.3.5 项目重现。
spring-boot-starter-actuator依赖与management.port
的用法
在 application.properties
中定义会导致启动嵌入式 tomcat 容器失败。
从 application.properties
中删除 management.port
属性 定义会使应用程序重新启动。
值得注意的是,虽然删除 属性 修复了问题,但原因尚不清楚。
可在此处找到此问题的解决方案:
https://github.com/spring-projects/spring-boot/issues/6193
并创建一个单独的 class 扩展 TomcatEmbeddedServletContainerFactory 并且其中 class 有一个 public 构造函数 class 超级。 class extending TomcatEmbeddedServletContainerFactory 不能是一个内部的class,它必须在它自己的文件中并且public在包中,否则错误不会消失。
Spring 从 1.3.3 升级到 1.3.5 后启动应用程序无法启动。 Spring 无法启动嵌入式容器 (Tomcat 8) 并显示以下错误消息:
org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'embeddedServletContainerFactory': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [wad.config.HttpsConfiguration]: No default constructor found; nested exception is java.lang.NoSuchMethodException: wad.config.HttpsConfiguration.()
基本上这个错误消息说它不能创建 embeddedServletContainerFactory
,但我不清楚 [wad.config.HttpsConfiguration]
指的是什么。 Java 配置 class 本身在包 wad.config
中并命名为 HttpsConfiguration
。
我试图将空构造函数添加到我的 HttpsConfiguration.java
但它没有帮助。
以下是我的 POM 的相关部分:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.5.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
...
</dependencies>
我的申请class:
@EntityScan(
basePackageClasses = {Application.class, Jsr310JpaConverters.class}
)
@SpringBootApplication
@Import({DevProfile.class})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
这是我的端口重定向配置,从 8080 -> 8443(可通过 application.properties 配置):
@Configuration
public class HttpsConfiguration {
@Value("${server.port}")
private int httpsPort;
@Value("${server.port.http}")
private int httpPort;
@Bean
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory() {
@Override
protected void postProcessContext(Context context) {
SecurityConstraint securityConstraint = new SecurityConstraint();
securityConstraint.setUserConstraint("CONFIDENTIAL");
SecurityCollection collection = new SecurityCollection();
collection.addPattern("/*");
securityConstraint.addCollection(collection);
context.addConstraint(securityConstraint);
}
};
tomcat.addAdditionalTomcatConnectors(initiateHttpConnector());
return tomcat;
}
// redirect from (http) port to (https) if https is enabled.
private Connector initiateHttpConnector() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setScheme("http");
connector.setPort(httpPort);
connector.setSecure(false);
connector.setRedirectPort(httpsPort);
return connector;
}
application.properties 配置:
...
#Actuator port
management.port = 9001
#HTTPS port
server.port=8443
#HTTP port
server.port.http=8080
#Enable SSL
server.ssl.enabled=true
...
更新:
问题可以通过 Spring 配置有上述 POM、application.properties 和 HttpSecurity & Application classes 的 Boot 1.3.5 项目重现。
spring-boot-starter-actuator依赖与management.port
的用法
在 application.properties
中定义会导致启动嵌入式 tomcat 容器失败。
从 application.properties
中删除 management.port
属性 定义会使应用程序重新启动。
值得注意的是,虽然删除 属性 修复了问题,但原因尚不清楚。
可在此处找到此问题的解决方案:
https://github.com/spring-projects/spring-boot/issues/6193
并创建一个单独的 class 扩展 TomcatEmbeddedServletContainerFactory 并且其中 class 有一个 public 构造函数 class 超级。 class extending TomcatEmbeddedServletContainerFactory 不能是一个内部的class,它必须在它自己的文件中并且public在包中,否则错误不会消失。