Skip to content

Commit 6717fca

Browse files
committed
Explicitly use original ClassLoader in case of package visibility
Closes gh-34684 (cherry picked from commit 6bb964e)
1 parent 86ea700 commit 6717fca

File tree

2 files changed

+28
-2
lines changed

2 files changed

+28
-2
lines changed

spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassEnhancer.java

+26
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,12 @@ public Class<?> enhance(Class<?> configClass, @Nullable ClassLoader classLoader)
116116
boolean classLoaderMismatch = (classLoader != null && classLoader != configClass.getClassLoader());
117117
if (classLoaderMismatch && classLoader instanceof SmartClassLoader smartClassLoader) {
118118
classLoader = smartClassLoader.getOriginalClassLoader();
119+
classLoaderMismatch = (classLoader != configClass.getClassLoader());
120+
}
121+
// Use original ClassLoader if config class relies on package visibility
122+
if (classLoaderMismatch && reliesOnPackageVisibility(configClass)) {
123+
classLoader = configClass.getClassLoader();
124+
classLoaderMismatch = false;
119125
}
120126
Enhancer enhancer = newEnhancer(configClass, classLoader);
121127
Class<?> enhancedClass = createClass(enhancer, classLoaderMismatch);
@@ -132,6 +138,26 @@ public Class<?> enhance(Class<?> configClass, @Nullable ClassLoader classLoader)
132138
}
133139
}
134140

141+
/**
142+
* Checks whether the given config class relies on package visibility,
143+
* either for the class itself or for any of its {@code @Bean} methods.
144+
*/
145+
private boolean reliesOnPackageVisibility(Class<?> configSuperClass) {
146+
int mod = configSuperClass.getModifiers();
147+
if (!Modifier.isPublic(mod) && !Modifier.isProtected(mod)) {
148+
return true;
149+
}
150+
for (Method method : ReflectionUtils.getDeclaredMethods(configSuperClass)) {
151+
if (BeanAnnotationHelper.isBeanAnnotated(method)) {
152+
mod = method.getModifiers();
153+
if (!Modifier.isPublic(mod) && !Modifier.isProtected(mod)) {
154+
return true;
155+
}
156+
}
157+
}
158+
return false;
159+
}
160+
135161
/**
136162
* Creates a new CGLIB {@link Enhancer} instance.
137163
*/

spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassEnhancerTests.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ void withNonPublicMethod() {
111111
ClassLoader classLoader = new URLClassLoader(new URL[0], getClass().getClassLoader());
112112
Class<?> enhancedClass = configurationClassEnhancer.enhance(MyConfigWithNonPublicMethod.class, classLoader);
113113
assertThat(MyConfigWithNonPublicMethod.class).isAssignableFrom(enhancedClass);
114-
assertThat(enhancedClass.getClassLoader()).isEqualTo(classLoader);
114+
assertThat(enhancedClass.getClassLoader()).isEqualTo(classLoader.getParent());
115115

116116
classLoader = new OverridingClassLoader(getClass().getClassLoader());
117117
enhancedClass = configurationClassEnhancer.enhance(MyConfigWithNonPublicMethod.class, classLoader);
@@ -126,7 +126,7 @@ void withNonPublicMethod() {
126126
classLoader = new BasicSmartClassLoader(getClass().getClassLoader());
127127
enhancedClass = configurationClassEnhancer.enhance(MyConfigWithNonPublicMethod.class, classLoader);
128128
assertThat(MyConfigWithNonPublicMethod.class).isAssignableFrom(enhancedClass);
129-
assertThat(enhancedClass.getClassLoader()).isEqualTo(classLoader);
129+
assertThat(enhancedClass.getClassLoader()).isEqualTo(classLoader.getParent());
130130
}
131131

132132

0 commit comments

Comments
 (0)