diff --git a/spring-boot/src/main/java/org/springframework/boot/context/listener/ConfigFileApplicationListener.java b/spring-boot/src/main/java/org/springframework/boot/context/listener/ConfigFileApplicationListener.java index e6943ac13ed..4dbf87f472e 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/listener/ConfigFileApplicationListener.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/listener/ConfigFileApplicationListener.java @@ -87,8 +87,8 @@ public class ConfigFileApplicationListener implements private static final String LOCATION_VARIABLE = "${spring.config.location}"; - private String[] searchLocations = new String[] { "classpath:", "file:./", - "classpath:config/", "file:./config/" }; + private String[] searchLocations = new String[] { "classpath:/", "file:./", + "classpath:/config/", "file:./config/" }; private String names = "${spring.config.name:application}"; @@ -147,24 +147,39 @@ public class ConfigFileApplicationListener implements PropertySource defaultProperties = environment.getPropertySources().remove( "defaultProperties"); + addActiveProfiles(environment); String firstPropertySourceName = loadInitial(environment, resourceLoader, candidates); - if (environment.containsProperty(ACTIVE_PROFILES_PROPERTY)) { - for (String activeProfile : StringUtils.commaDelimitedListToSet(environment - .getProperty(ACTIVE_PROFILES_PROPERTY).toString())) { - environment.addActiveProfile(activeProfile); - } + // Repeatedly load property sources in case additional profiles are activated + int numberOfPropertySources; + do { + numberOfPropertySources = environment.getPropertySources().size(); + addActiveProfiles(environment); + loadAgain(environment, resourceLoader, candidates, firstPropertySourceName); } - - // Second load for specific profiles - loadAgain(environment, resourceLoader, candidates, firstPropertySourceName); + while (environment.getPropertySources().size() > numberOfPropertySources); if (defaultProperties != null) { environment.getPropertySources().addLast(defaultProperties); } } + /** + * @param environment + */ + private void addActiveProfiles(ConfigurableEnvironment environment) { + for (PropertySource propertySource : environment.getPropertySources()) { + if (propertySource.containsProperty(ACTIVE_PROFILES_PROPERTY)) { + Object profiles = propertySource.getProperty(ACTIVE_PROFILES_PROPERTY); + for (String profile : StringUtils.commaDelimitedListToSet(profiles + .toString())) { + environment.addActiveProfile(profile); + } + } + } + } + private String loadInitial(ConfigurableEnvironment environment, ResourceLoader resourceLoader, LoadCandidates candidates) { String firstSourceName = null; diff --git a/spring-boot/src/test/java/org/springframework/boot/ReproTests.java b/spring-boot/src/test/java/org/springframework/boot/ReproTests.java new file mode 100644 index 00000000000..c347c0d3ffe --- /dev/null +++ b/spring-boot/src/test/java/org/springframework/boot/ReproTests.java @@ -0,0 +1,50 @@ +/* + * Copyright 2012-2014 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.Test; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Configuration; + +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertThat; + +/** + * Tests to reproduce reported issues. + * + * @author Phillip Webb + */ +public class ReproTests { + + @Test + public void enableProfileViaApplicationProperties() throws Exception { + // gh-308 + SpringApplication application = new SpringApplication(Config.class); + + application.setWebEnvironment(false); + ConfigurableApplicationContext context = application.run( + "--spring.config.name=enableprofileviaapplicationproperties", + "--spring.profiles.active=dev"); + assertThat(context.getEnvironment().acceptsProfiles("dev"), equalTo(true)); + assertThat(context.getEnvironment().acceptsProfiles("a"), equalTo(true)); + } + + @Configuration + public static class Config { + + } +} diff --git a/spring-boot/src/test/java/org/springframework/boot/context/listener/ConfigFileApplicationListenerTests.java b/spring-boot/src/test/java/org/springframework/boot/context/listener/ConfigFileApplicationListenerTests.java index 76f4cddc424..aacb82f6539 100644 --- a/spring-boot/src/test/java/org/springframework/boot/context/listener/ConfigFileApplicationListenerTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/context/listener/ConfigFileApplicationListenerTests.java @@ -186,8 +186,8 @@ public class ConfigFileApplicationListenerTests { "spring.profiles.active:prod"); this.initializer.setNames("testsetprofiles"); this.initializer.onApplicationEvent(this.event); - assertThat(Arrays.asList(this.environment.getActiveProfiles()).toString(), - equalTo("[prod]")); + assertThat(this.environment.getActiveProfiles(), equalTo(new String[] { "prod", + "dev" })); } @Test @@ -212,7 +212,7 @@ public class ConfigFileApplicationListenerTests { // The default property source is still there assertThat( this.environment.getPropertySources().contains( - "classpath:application.properties"), is(true)); + "classpath:/application.properties"), is(true)); assertThat(this.environment.getProperty("foo"), equalTo("bucket")); } @@ -347,11 +347,27 @@ public class ConfigFileApplicationListenerTests { context.close(); } + @Test + public void activateProfileFromProfileSpecificProperties() throws Exception { + SpringApplication application = new SpringApplication(Config.class); + application.setWebEnvironment(false); + ConfigurableApplicationContext context = application + .run("--spring.profiles.active=activateprofile"); + assertThat(context.getEnvironment().acceptsProfiles("activateprofile"), + equalTo(true)); + assertThat(context.getEnvironment().acceptsProfiles("specific"), equalTo(true)); + } + @Test public void defaultApplicationProperties() throws Exception { } + @Configuration + protected static class Config { + + } + @Configuration @PropertySource("classpath:/specificlocation.properties") protected static class WithPropertySource { diff --git a/spring-boot/src/test/resources/application-activateprofile.properties b/spring-boot/src/test/resources/application-activateprofile.properties new file mode 100644 index 00000000000..42970aaa301 --- /dev/null +++ b/spring-boot/src/test/resources/application-activateprofile.properties @@ -0,0 +1 @@ +spring.profiles.active=specific diff --git a/spring-boot/src/test/resources/enableprofileviaapplicationproperties.yml b/spring-boot/src/test/resources/enableprofileviaapplicationproperties.yml new file mode 100644 index 00000000000..afdf33c9b0e --- /dev/null +++ b/spring-boot/src/test/resources/enableprofileviaapplicationproperties.yml @@ -0,0 +1,3 @@ +spring: + profiles: + active: a \ No newline at end of file