Check for package-visible constructor in case of ClassLoader mismatch
Closes gh-34950
This commit is contained in:
parent
53844b068c
commit
15d1455acb
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
package org.springframework.context.annotation;
|
package org.springframework.context.annotation;
|
||||||
|
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
|
@ -139,14 +140,20 @@ class ConfigurationClassEnhancer {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether the given config class relies on package visibility,
|
* Checks whether the given config class relies on package visibility, either for
|
||||||
* either for the class itself or for any of its {@code @Bean} methods.
|
* the class and any of its constructors or for any of its {@code @Bean} methods.
|
||||||
*/
|
*/
|
||||||
private boolean reliesOnPackageVisibility(Class<?> configSuperClass) {
|
private boolean reliesOnPackageVisibility(Class<?> configSuperClass) {
|
||||||
int mod = configSuperClass.getModifiers();
|
int mod = configSuperClass.getModifiers();
|
||||||
if (!Modifier.isPublic(mod) && !Modifier.isProtected(mod)) {
|
if (!Modifier.isPublic(mod) && !Modifier.isProtected(mod)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
for (Constructor<?> ctor : configSuperClass.getDeclaredConstructors()) {
|
||||||
|
mod = ctor.getModifiers();
|
||||||
|
if (!Modifier.isPublic(mod) && !Modifier.isProtected(mod)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
for (Method method : ReflectionUtils.getDeclaredMethods(configSuperClass)) {
|
for (Method method : ReflectionUtils.getDeclaredMethods(configSuperClass)) {
|
||||||
if (BeanAnnotationHelper.isBeanAnnotated(method)) {
|
if (BeanAnnotationHelper.isBeanAnnotated(method)) {
|
||||||
mod = method.getModifiers();
|
mod = method.getModifiers();
|
||||||
|
|
|
@ -104,6 +104,31 @@ class ConfigurationClassEnhancerTests {
|
||||||
assertThat(enhancedClass.getClassLoader()).isEqualTo(classLoader.getParent());
|
assertThat(enhancedClass.getClassLoader()).isEqualTo(classLoader.getParent());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void withNonPublicConstructor() {
|
||||||
|
ConfigurationClassEnhancer configurationClassEnhancer = new ConfigurationClassEnhancer();
|
||||||
|
|
||||||
|
ClassLoader classLoader = new URLClassLoader(new URL[0], getClass().getClassLoader());
|
||||||
|
Class<?> enhancedClass = configurationClassEnhancer.enhance(MyConfigWithNonPublicConstructor.class, classLoader);
|
||||||
|
assertThat(MyConfigWithNonPublicConstructor.class).isAssignableFrom(enhancedClass);
|
||||||
|
assertThat(enhancedClass.getClassLoader()).isEqualTo(classLoader.getParent());
|
||||||
|
|
||||||
|
classLoader = new OverridingClassLoader(getClass().getClassLoader());
|
||||||
|
enhancedClass = configurationClassEnhancer.enhance(MyConfigWithNonPublicConstructor.class, classLoader);
|
||||||
|
assertThat(MyConfigWithNonPublicConstructor.class).isAssignableFrom(enhancedClass);
|
||||||
|
assertThat(enhancedClass.getClassLoader()).isEqualTo(classLoader.getParent());
|
||||||
|
|
||||||
|
classLoader = new CustomSmartClassLoader(getClass().getClassLoader());
|
||||||
|
enhancedClass = configurationClassEnhancer.enhance(MyConfigWithNonPublicConstructor.class, classLoader);
|
||||||
|
assertThat(MyConfigWithNonPublicConstructor.class).isAssignableFrom(enhancedClass);
|
||||||
|
assertThat(enhancedClass.getClassLoader()).isEqualTo(classLoader.getParent());
|
||||||
|
|
||||||
|
classLoader = new BasicSmartClassLoader(getClass().getClassLoader());
|
||||||
|
enhancedClass = configurationClassEnhancer.enhance(MyConfigWithNonPublicConstructor.class, classLoader);
|
||||||
|
assertThat(MyConfigWithNonPublicConstructor.class).isAssignableFrom(enhancedClass);
|
||||||
|
assertThat(enhancedClass.getClassLoader()).isEqualTo(classLoader.getParent());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void withNonPublicMethod() {
|
void withNonPublicMethod() {
|
||||||
ConfigurationClassEnhancer configurationClassEnhancer = new ConfigurationClassEnhancer();
|
ConfigurationClassEnhancer configurationClassEnhancer = new ConfigurationClassEnhancer();
|
||||||
|
@ -160,6 +185,19 @@ class ConfigurationClassEnhancerTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public static class MyConfigWithNonPublicConstructor {
|
||||||
|
|
||||||
|
MyConfigWithNonPublicConstructor() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public String myBean() {
|
||||||
|
return "bean";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
public static class MyConfigWithNonPublicMethod {
|
public static class MyConfigWithNonPublicMethod {
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue