Remove support for deprecated Java SecurityManager (-> JDK 17 build compatibility)

Includes hard JDK 9+ API dependency in CGLIB ReflectUtils (Lookup.defineClass) and removal of OutputStream spy proxy usage (avoiding invalid Mockito proxy on JDK 17)

Closes gh-26901
This commit is contained in:
Juergen Hoeller
2021-09-15 15:30:25 +02:00
parent 0640da74bc
commit cf2429b0f0
47 changed files with 147 additions and 2078 deletions

View File

@@ -23,8 +23,6 @@ import java.io.Reader;
import java.io.Serializable;
import java.net.URI;
import java.net.URL;
import java.security.AccessControlException;
import java.security.Permission;
import java.util.Optional;
import java.util.Properties;
@@ -237,43 +235,6 @@ class ApplicationContextExpressionTests {
}
}
@Test
void systemPropertiesSecurityManager() {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
GenericBeanDefinition bd = new GenericBeanDefinition();
bd.setBeanClass(TestBean.class);
bd.getPropertyValues().add("country", "#{systemProperties.country}");
ac.registerBeanDefinition("tb", bd);
SecurityManager oldSecurityManager = System.getSecurityManager();
try {
System.setProperty("country", "NL");
SecurityManager securityManager = new SecurityManager() {
@Override
public void checkPropertiesAccess() {
throw new AccessControlException("Not Allowed");
}
@Override
public void checkPermission(Permission perm) {
// allow everything else
}
};
System.setSecurityManager(securityManager);
ac.refresh();
TestBean tb = ac.getBean("tb", TestBean.class);
assertThat(tb.getCountry()).isEqualTo("NL");
}
finally {
System.setSecurityManager(oldSecurityManager);
System.getProperties().remove("country");
}
ac.close();
}
@Test
void stringConcatenationWithDebugLogging() {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();

View File

@@ -1,119 +0,0 @@
/*
* Copyright 2002-2019 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
*
* https://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.context.support;
import java.security.AccessControlException;
import java.security.Permission;
import java.util.Map;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.AnnotatedBeanDefinitionReader;
import org.springframework.context.annotation.Profile;
import org.springframework.core.env.AbstractEnvironment;
import org.springframework.core.testfixture.env.EnvironmentTestUtils;
import org.springframework.stereotype.Component;
import static java.lang.String.format;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests integration between Environment and SecurityManagers. See SPR-9970.
*
* @author Chris Beams
*/
public class EnvironmentSecurityManagerIntegrationTests {
private SecurityManager originalSecurityManager;
private Map<String, String> env;
@BeforeEach
public void setUp() {
originalSecurityManager = System.getSecurityManager();
env = EnvironmentTestUtils.getModifiableSystemEnvironment();
env.put(AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME, "p1");
}
@AfterEach
public void tearDown() {
env.remove(AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME);
System.setSecurityManager(originalSecurityManager);
}
@Test
public void securityManagerDisallowsAccessToSystemEnvironmentButAllowsAccessToIndividualKeys() {
SecurityManager securityManager = new SecurityManager() {
@Override
public void checkPermission(Permission perm) {
// Disallowing access to System#getenv means that our
// ReadOnlySystemAttributesMap will come into play.
if ("getenv.*".equals(perm.getName())) {
throw new AccessControlException("Accessing the system environment is disallowed");
}
}
};
System.setSecurityManager(securityManager);
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
AnnotatedBeanDefinitionReader reader = new AnnotatedBeanDefinitionReader(bf);
reader.register(C1.class);
assertThat(bf.containsBean("c1")).isTrue();
}
@Test
public void securityManagerDisallowsAccessToSystemEnvironmentAndDisallowsAccessToIndividualKey() {
SecurityManager securityManager = new SecurityManager() {
@Override
public void checkPermission(Permission perm) {
// Disallowing access to System#getenv means that our
// ReadOnlySystemAttributesMap will come into play.
if ("getenv.*".equals(perm.getName())) {
throw new AccessControlException("Accessing the system environment is disallowed");
}
// Disallowing access to the spring.profiles.active property means that
// the BeanDefinitionReader won't be able to determine which profiles are
// active. We should see an INFO-level message in the console about this
// and as a result, any components marked with a non-default profile will
// be ignored.
if (("getenv." + AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME).equals(perm.getName())) {
throw new AccessControlException(
format("Accessing system environment variable [%s] is disallowed",
AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME));
}
}
};
System.setSecurityManager(securityManager);
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
AnnotatedBeanDefinitionReader reader = new AnnotatedBeanDefinitionReader(bf);
reader.register(C1.class);
assertThat(bf.containsBean("c1")).isFalse();
}
@Component("c1")
@Profile("p1")
static class C1 {
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 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.
@@ -19,8 +19,6 @@ package org.springframework.jmx.support;
import java.beans.PropertyDescriptor;
import javax.management.DynamicMBean;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName;
@@ -57,42 +55,42 @@ class JmxUtilsTests {
}
@Test
void isMBeanWithDynamicMBean() throws Exception {
void isMBeanWithDynamicMBean() {
DynamicMBean mbean = new TestDynamicMBean();
assertThat(JmxUtils.isMBean(mbean.getClass())).as("Dynamic MBean not detected correctly").isTrue();
}
@Test
void isMBeanWithStandardMBeanWrapper() throws Exception {
void isMBeanWithStandardMBeanWrapper() throws NotCompliantMBeanException {
StandardMBean mbean = new StandardMBean(new JmxTestBean(), IJmxTestBean.class);
assertThat(JmxUtils.isMBean(mbean.getClass())).as("Standard MBean not detected correctly").isTrue();
}
@Test
void isMBeanWithStandardMBeanInherited() throws Exception {
void isMBeanWithStandardMBeanInherited() throws NotCompliantMBeanException {
StandardMBean mbean = new StandardMBeanImpl();
assertThat(JmxUtils.isMBean(mbean.getClass())).as("Standard MBean not detected correctly").isTrue();
}
@Test
void notAnMBean() throws Exception {
void notAnMBean() {
assertThat(JmxUtils.isMBean(Object.class)).as("Object incorrectly identified as an MBean").isFalse();
}
@Test
void simpleMBean() throws Exception {
void simpleMBean() {
Foo foo = new Foo();
assertThat(JmxUtils.isMBean(foo.getClass())).as("Simple MBean not detected correctly").isTrue();
}
@Test
void simpleMXBean() throws Exception {
void simpleMXBean() {
FooX foo = new FooX();
assertThat(JmxUtils.isMBean(foo.getClass())).as("Simple MXBean not detected correctly").isTrue();
}
@Test
void simpleMBeanThroughInheritance() throws Exception {
void simpleMBeanThroughInheritance() {
Bar bar = new Bar();
Abc abc = new Abc();
assertThat(JmxUtils.isMBean(bar.getClass())).as("Simple MBean (through inheritance) not detected correctly").isTrue();
@@ -126,19 +124,6 @@ class JmxUtilsTests {
assertThat(uniqueName.getKeyProperty(JmxUtils.IDENTITY_OBJECT_NAME_KEY)).as("Identity key is incorrect").isEqualTo(ObjectUtils.getIdentityHexString(managedResource));
}
@Test
void locatePlatformMBeanServer() {
MBeanServer server = null;
try {
server = JmxUtils.locateMBeanServer();
}
finally {
if (server != null) {
MBeanServerFactory.releaseMBeanServer(server);
}
}
}
public static class AttributeTestBean {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 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.
@@ -47,7 +47,7 @@ class MBeanServerFactoryBeanTests {
}
@Test
void defaultValues() throws Exception {
void defaultValues() {
MBeanServerFactoryBean bean = new MBeanServerFactoryBean();
bean.afterPropertiesSet();
try {
@@ -60,7 +60,7 @@ class MBeanServerFactoryBeanTests {
}
@Test
void defaultDomain() throws Exception {
void defaultDomain() {
MBeanServerFactoryBean bean = new MBeanServerFactoryBean();
bean.setDefaultDomain("foo");
bean.afterPropertiesSet();
@@ -129,7 +129,8 @@ class MBeanServerFactoryBeanTests {
assertCreation(false, "The server should not be available in the list");
}
private void assertCreation(boolean referenceShouldExist, String failMsg) throws Exception {
private void assertCreation(boolean referenceShouldExist, String failMsg) {
MBeanServerFactoryBean bean = new MBeanServerFactoryBean();
bean.setRegisterWithFactory(referenceShouldExist);
bean.afterPropertiesSet();

View File

@@ -1,52 +0,0 @@
/*
* Copyright 2002-2019 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
*
* https://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.jndi;
import java.lang.reflect.Field;
import javax.naming.spi.NamingManager;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link JndiLocatorDelegate}.
*
* @author Phillip Webb
* @author Juergen Hoeller
*/
public class JndiLocatorDelegateTests {
@Test
public void isDefaultJndiEnvironmentAvailableFalse() throws Exception {
Field builderField = NamingManager.class.getDeclaredField("initctx_factory_builder");
builderField.setAccessible(true);
Object oldBuilder = builderField.get(null);
builderField.set(null, null);
try {
assertThat(JndiLocatorDelegate.isDefaultJndiEnvironmentAvailable()).isEqualTo(false);
}
finally {
builderField.set(null, oldBuilder);
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 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.
@@ -16,9 +16,6 @@
package org.springframework.util;
import java.lang.management.ManagementFactory;
import java.lang.reflect.Field;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
@@ -45,10 +42,6 @@ public class MBeanTestUtils {
}
}
}
Field field = ManagementFactory.class.getDeclaredField("platformMBeanServer");
field.setAccessible(true);
field.set(null, null);
}
}