首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何禁用undertow的自动配置

如何禁用undertow的自动配置
EN

Stack Overflow用户
提问于 2018-12-18 03:10:10
回答 1查看 1.3K关注 0票数 3

我有一个使用spring-boot-starter-web的普通spring-boot web应用程序,也就是一个嵌入式tomcat。

现在,我用来测试的其中一个库将undertow作为依赖项(因为它本身启动了一个用于模拟外部依赖的嵌入式web服务器),这似乎使spring-boot自动配置尝试将undertow配置为嵌入式web服务器(由于版本不匹配,它似乎会崩溃,这也不是我想要的-我将tomcat作为我的服务器)。

这是our test class

代码语言:javascript
复制
package org.zalando.nakadiproducer.tests;

[... imports skipped ...]

import static io.restassured.RestAssured.given;

@RunWith(SpringRunner.class)
@SpringBootTest(
        // This line looks like that by intention: We want to test that the MockNakadiPublishingClient will be picked up
        // by our starter *even if* it has been defined *after* the application itself. This has been a problem until
        // this commit.
        classes = { Application.class, MockNakadiConfig.class  },
        webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT
)
//@EnableAutoConfiguration(exclude=EmbeddedWebServerFactoryCustomizerAutoConfiguration.class)
public class ApplicationIT {
    @LocalManagementPort
    private int localManagementPort;

    @ClassRule
    public static final EnvironmentVariables environmentVariables
            = new EnvironmentVariables();

    @BeforeClass
    public static void fakeCredentialsDir() {
        environmentVariables.set("CREDENTIALS_DIR", new File("src/main/test/tokens").getAbsolutePath());
    }

    @Test
    public void shouldSuccessfullyStartAndSnapshotCanBeTriggered() {
        given().baseUri("http://localhost:" + localManagementPort).contentType("application/json")
        .when().post("/actuator/snapshot-event-creation/eventtype")
        .then().statusCode(204);
    }
}

使用main application class

代码语言:javascript
复制
package org.zalando.nakadiproducer.tests;

[imports skipped]

@EnableAutoConfiguration
@EnableNakadiProducer
public class Application {

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

    @Bean
    @Primary
    public DataSource dataSource() throws IOException {
        return embeddedPostgres().getPostgresDatabase();
    }

    @Bean
    public EmbeddedPostgres embeddedPostgres() throws IOException {
        return EmbeddedPostgres.start();
    }

    @Bean
    public SnapshotEventGenerator snapshotEventGenerator() {
        return new SimpleSnapshotEventGenerator("eventtype", (withIdGreaterThan, filter) -> {
            if (withIdGreaterThan == null) {
                return Collections.singletonList(new Snapshot("1", "foo", filter));
            } else if (withIdGreaterThan.equals("1")) {
                return Collections.singletonList(new Snapshot("2", "foo", filter));
            } else {
                return new ArrayList<>();
            }
        });

        // Todo: Test that some events arrive at a local nakadi mock
    }
}

以下是错误消息:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'undertowWebServerFactoryCustomizer' defined in class path resource [org/springframework/boot/autoconfigure/web/embedded/EmbeddedWebServerFactoryCustomizerAutoConfiguration$UndertowWebServerFactoryCustomizerConfiguration.class]: Post-processing of merged bean definition failed; nested exception is java.lang.IllegalStateException: Failed to introspect Class [org.springframework.boot.autoconfigure.web.embedded.UndertowWebServerFactoryCustomizer] from ClassLoader [sun.misc.Launcher$AppClassLoader@378fd1ac]

上面提到的定义类在spring-boot-autoconfigure 2.0.3.RELEASE中,如下所示:

代码语言:javascript
复制
@Configuration
@EnableConfigurationProperties(ServerProperties.class)
public class EmbeddedWebServerFactoryCustomizerAutoConfiguration {

    @ConditionalOnClass({ Tomcat.class, UpgradeProtocol.class })
    public static class TomcatWebServerFactoryCustomizerConfiguration {

 // tomcat, jetty

    /**
     * Nested configuration if Undertow is being used.
     */
    @Configuration
    @ConditionalOnClass({ Undertow.class, SslClientAuthMode.class })
    public static class UndertowWebServerFactoryCustomizerConfiguration {

        @Bean
        public UndertowWebServerFactoryCustomizer undertowWebServerFactoryCustomizer(
                Environment environment, ServerProperties serverProperties) {
            return new UndertowWebServerFactoryCustomizer(environment, serverProperties);
        }
    }
}

我如何告诉spring-boot不要配置Undertow?

我在我的测试类(除了@SpringBootTest之外)上尝试了@EnableAutoConfiguration(exclude=EmbeddedWebServerFactoryCustomizerAutoConfiguration.class),但没有任何效果。

如果我尝试使用@EnableAutoConfiguration(exclude=EmbeddedWebServerFactoryCustomizerAutoConfiguration.UndertowWebServerFactoryCustomizerConfiguration.class),我会得到这个错误:

代码语言:javascript
复制
Caused by: java.lang.IllegalStateException: The following classes could not be excluded because they are not auto-configuration classes:
    - org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration$UndertowWebServerFactoryCustomizerConfiguration
EN

回答 1

Stack Overflow用户

发布于 2018-12-18 03:34:51

从项目的依赖项中删除Undertow是最安全的方法。Spring Boot基于类路径扫描,所以一旦Undertow从类路径中消失,它的自动配置将不会被处理。

EmbeddedWebServerFactoryCustomizerAutoConfiguration的问题在于它没有提供属性开关。它纯粹基于servlet容器类的存在。要删除它,您必须排除整个EmbeddedWebServerFactoryCustomizerAutoConfiguration

代码语言:javascript
复制
@EnableAutoConfiguration(exclude=EmbeddedWebServerFactoryCustomizerAutoConfiguration.class)
public MyTest {

}

在您的测试配置中,只定义启动Tomcat的bean:

代码语言:javascript
复制
@TestConfiguraton
@EnableConfigurationProperties(ServerProperties.class)
public MyTestConfig {

  @Bean
  public TomcatWebServerFactoryCustomizer tomcatWebServerFactoryCustomizer(Environment environment, ServerProperties serverProperties) {
    return new TomcatWebServerFactoryCustomizer(environment, serverProperties);
  }

}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53821609

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档