diff --git a/spring-core/src/main/java/org/springframework/core/env/SystemEnvironmentPropertySource.java b/spring-core/src/main/java/org/springframework/core/env/SystemEnvironmentPropertySource.java index a9a02fd606..c7f0fd6f74 100644 --- a/spring-core/src/main/java/org/springframework/core/env/SystemEnvironmentPropertySource.java +++ b/spring-core/src/main/java/org/springframework/core/env/SystemEnvironmentPropertySource.java @@ -63,6 +63,9 @@ import org.springframework.util.ObjectUtils; */ public class SystemEnvironmentPropertySource extends MapPropertySource { + /** if SecurityManager scenarios mean that property access should be via getPropertyNames() */ + private boolean usePropertyNames; + /** * Create a new {@code SystemEnvironmentPropertySource} with the given name and * delegating to the given {@code MapPropertySource}. @@ -102,29 +105,48 @@ public class SystemEnvironmentPropertySource extends MapPropertySource { */ private String resolvePropertyName(String name) { Assert.notNull(name, "Property name must not be null"); - if (ObjectUtils.containsElement(getPropertyNames(), name)) { - return name; - } - - String usName = name.replace('.', '_'); - if (!name.equals(usName) && ObjectUtils.containsElement(getPropertyNames(), usName)) { - return usName; - } - - String ucName = name.toUpperCase(); - if (!name.equals(ucName)) { - if (ObjectUtils.containsElement(getPropertyNames(), ucName)) { - return ucName; + try { + String[] propertyNames = (this.usePropertyNames ? getPropertyNames() : null); + if (containsProperty(propertyNames, name)) { + return name; } - else { - String usUcName = ucName.replace('.', '_'); - if (!ucName.equals(usUcName) && ObjectUtils.containsElement(getPropertyNames(), usUcName)) { - return usUcName; + + String usName = name.replace('.', '_'); + if (!name.equals(usName) && containsProperty(propertyNames, usName)) { + return usName; + } + + String ucName = name.toUpperCase(); + if (!name.equals(ucName)) { + if (containsProperty(propertyNames, ucName)) { + return ucName; + } + else { + String usUcName = ucName.replace('.', '_'); + if (!ucName.equals(usUcName) && containsProperty(propertyNames, usUcName)) { + return usUcName; + } } } - } - return name; + return name; + } + catch (RuntimeException ex) { + if (this.usePropertyNames) { + throw ex; + } + else { + this.usePropertyNames = true; + return resolvePropertyName(name); + } + } + } + + private boolean containsProperty(String[] propertyNames, String name) { + if (propertyNames == null) { + return super.containsProperty(name); + } + return ObjectUtils.containsElement(propertyNames, name); } } diff --git a/spring-core/src/test/java/org/springframework/core/env/SystemEnvironmentPropertySourceTests.java b/spring-core/src/test/java/org/springframework/core/env/SystemEnvironmentPropertySourceTests.java index 880868eefd..d705458267 100644 --- a/spring-core/src/test/java/org/springframework/core/env/SystemEnvironmentPropertySourceTests.java +++ b/spring-core/src/test/java/org/springframework/core/env/SystemEnvironmentPropertySourceTests.java @@ -16,15 +16,15 @@ package org.springframework.core.env; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.junit.Assert.assertThat; - import java.util.HashMap; import java.util.Map; import org.junit.Before; import org.junit.Test; +import static org.hamcrest.CoreMatchers.*; +import static org.junit.Assert.*; + /** * Unit tests for {@link SystemEnvironmentPropertySource}. * @@ -101,4 +101,18 @@ public class SystemEnvironmentPropertySourceTests { assertThat(ps.getProperty("a.key"), equalTo((Object)"a_value")); } + @Test + public void withSecurityConstraints() throws Exception { + envMap = new HashMap() { + @Override + public boolean containsKey(Object key) { + throw new UnsupportedOperationException(); + } + }; + ps = new SystemEnvironmentPropertySource("sysEnv", envMap); + envMap.put("A_KEY", "a_value"); + assertThat(ps.containsProperty("A_KEY"), equalTo(true)); + assertThat(ps.getProperty("A_KEY"), equalTo((Object)"a_value")); + } + }