【问题标题】:Embedded tomcat fails to start when upgraded from Spring Boot 1.3.3 -> 1.3.5从 Spring Boot 1.3.3 -> 1.3.5 升级时嵌入式 tomcat 无法启动
【发布时间】:2016-10-07 05:56:46
【问题描述】:

从 1.3.3 升级到 1.3.5 后,Spring Boot 应用程序无法启动。 Spring 无法启动嵌入式容器(Tomcat 8)并显示以下错误消息:

org.springframework.context.ApplicationContextException:无法启动嵌入式容器;嵌套异常是 org.springframework.beans.factory.BeanCreationException:创建名为“embeddedServletContainerFactory”的 bean 时出错:bean 实例化失败;嵌套异常是 org.springframework.beans.BeanInstantiationException:无法实例化 [wad.config.HttpsConfiguration$1]:未找到默认构造函数;嵌套异常是 java.lang.NoSuchMethodException: wad.config.HttpsConfiguration$1.()

基本上这条错误消息说它无法创建embeddedServletContainerFactory,但我不清楚[wad.config.HttpsConfiguration$1] 指的是什么。 Java 配置类本身在包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>

我的应用程序类:

@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
...

更新:

问题可以通过配置上述 POM、application.properties 和 HttpSecurity & Application 类的 Spring Boot 1.3.5 项目重现。

【问题讨论】:

    标签: java spring spring-boot spring-java-config embedded-tomcat-8


    【解决方案1】:

    spring-boot-starter-actuator 依赖与management.port 的使用 在application.properties 中定义会导致启动嵌入式tomcat 容器失败。

    application.properties 中删除management.port 属性定义会使应用程序再次启动。

    值得注意的是,虽然删除该属性解决了问题,但原因尚不清楚。

    【讨论】:

      【解决方案2】:

      这个问题的解决方法可以在这里找到:

      https://github.com/spring-projects/spring-boot/issues/6193

      并创建一个扩展 TomcatEmbeddedServletContainerFactory 的单独类,并且在该类中具有该类超级的公共构造函数。扩展TomcatEmbeddedServletContainerFactory的类不能是内部类,必须在自己的文件中,并且在包中公开,否则错误不会消失。

      【讨论】:

        猜你喜欢
        • 2016-08-19
        • 1970-01-01
        • 2017-09-20
        • 1970-01-01
        • 2020-07-24
        • 2023-03-26
        • 2019-03-13
        • 1970-01-01
        • 2017-01-10
        相关资源
        最近更新 更多