From febaf15b61b46829644afe47ab14ecce9058c146 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Fri, 5 Oct 2018 16:41:03 +0200 Subject: [PATCH] Guard WebApplicationType detection in case spring web is not present Closes gh-14589 --- .../boot/SpringApplication.java | 20 ++++-- .../boot/SpringApplicationNoWebTests.java | 69 +++++++++++++++++++ 2 files changed, 84 insertions(+), 5 deletions(-) create mode 100644 spring-boot-project/spring-boot/src/test/java/org/springframework/boot/SpringApplicationNoWebTests.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java index f2b37604dc..1119f38bbe 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java @@ -43,7 +43,6 @@ import org.springframework.boot.Banner.Mode; import org.springframework.boot.context.properties.bind.Bindable; import org.springframework.boot.context.properties.bind.Binder; import org.springframework.boot.context.properties.source.ConfigurationPropertySources; -import org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext; import org.springframework.boot.web.reactive.context.StandardReactiveWebEnvironment; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextInitializer; @@ -76,7 +75,6 @@ import org.springframework.util.ObjectUtils; import org.springframework.util.ReflectionUtils; import org.springframework.util.StopWatch; import org.springframework.util.StringUtils; -import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.StandardServletEnvironment; /** @@ -1187,16 +1185,28 @@ public class SpringApplication { private WebApplicationType deduceWebApplicationType( Class applicationContextClass) { - if (WebApplicationContext.class.isAssignableFrom(applicationContextClass)) { + if (safeIsAssignableFrom("org.springframework.web.context.WebApplicationContext", + applicationContextClass)) { return WebApplicationType.SERVLET; } - if (ReactiveWebApplicationContext.class - .isAssignableFrom(applicationContextClass)) { + if (safeIsAssignableFrom( + "org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext", + applicationContextClass)) { return WebApplicationType.REACTIVE; } return WebApplicationType.NONE; } + private boolean safeIsAssignableFrom(String target, Class type) { + try { + Class targetClass = ClassUtils.forName(target, getClassLoader()); + return targetClass.isAssignableFrom(type); + } + catch (Throwable ex) { + return false; + } + } + /** * Sets the {@link ApplicationContextInitializer} that will be applied to the Spring * {@link ApplicationContext}. diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/SpringApplicationNoWebTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/SpringApplicationNoWebTests.java new file mode 100644 index 0000000000..bf30cd0720 --- /dev/null +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/SpringApplicationNoWebTests.java @@ -0,0 +1,69 @@ +/* + * Copyright 2012-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot; + +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.boot.testsupport.runner.classpath.ClassPathExclusions; +import org.springframework.boot.testsupport.runner.classpath.ModifiedClassPathRunner; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.support.StaticApplicationContext; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link SpringApplication} when spring web is not on the classpath. + * + * @author Stephane Nicoll + */ +@RunWith(ModifiedClassPathRunner.class) +@ClassPathExclusions("spring-web*.jar") +public class SpringApplicationNoWebTests { + + private ConfigurableApplicationContext context; + + @After + public void cleanUp() { + if (this.context != null) { + this.context.close(); + } + } + + @Test + public void detectWebApplicationTypeToNone() { + SpringApplication application = new SpringApplication(ExampleConfig.class); + assertThat(application.getWebApplicationType()) + .isEqualTo(WebApplicationType.NONE); + } + + @Test + public void specificApplicationContextClass() { + SpringApplication application = new SpringApplication(ExampleConfig.class); + application.setApplicationContextClass(StaticApplicationContext.class); + this.context = application.run(); + assertThat(this.context).isInstanceOf(StaticApplicationContext.class); + } + + @Configuration + static class ExampleConfig { + + } + +}