【发布时间】:2019-05-18 04:43:34
【问题描述】:
我有一个使用 spring-boot-starter-web 的普通 spring-boot Web 应用程序,即嵌入式 tomcat。
现在我用于测试的库之一带有 undertow 作为依赖项(因为它本身正在启动一个嵌入式 Web 服务器来模拟外部依赖项),这似乎让 spring-boot 自动配置尝试配置undertow 作为嵌入式 Web 服务器(它似乎由于版本不匹配而中断,而且也不是我想要的 - 我可以使用 tomcat 作为我的服务器)。
这里是our test class:
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);
}
}
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中,看起来像这样:
@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?
我在我的测试课上尝试了@EnableAutoConfiguration(exclude=EmbeddedWebServerFactoryCustomizerAutoConfiguration.class)(在@SpringBootTest 旁边),但没有效果。
如果我尝试@EnableAutoConfiguration(exclude=EmbeddedWebServerFactoryCustomizerAutoConfiguration.UndertowWebServerFactoryCustomizerConfiguration.class),我会收到此错误:
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
【问题讨论】:
-
能否请您添加正在使用 undertown 的依赖项?
-
我是nakadi-mock,我正在研究图书馆。我可以更改它,但这意味着更改该库的完整概念,我想避免这种情况。
标签: java spring spring-boot