Skip to content

Commit 81b4020

Browse files
committed
Do not load concrete types in annotation metadata
This change fixes a regression introduced in the previous commit. Closes gh-35252
1 parent 2b7f88e commit 81b4020

File tree

4 files changed

+62
-11
lines changed

4 files changed

+62
-11
lines changed

spring-core/spring-core.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ dependencies {
8888
optional("org.jetbrains.kotlin:kotlin-stdlib")
8989
optional("org.jetbrains.kotlinx:kotlinx-coroutines-core")
9090
optional("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
91+
testCompileOnly("com.github.ben-manes.caffeine:caffeine")
9192
testFixturesImplementation("io.projectreactor:reactor-test")
9293
testFixturesImplementation("org.assertj:assertj-core")
9394
testFixturesImplementation("org.junit.jupiter:junit-jupiter")

spring-core/src/main/java24/org/springframework/core/type/classreading/ClassFileAnnotationMetadata.java

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ static MergedAnnotations createMergedAnnotations(String className, RuntimeVisibl
8787
return createMergedAnnotation(className, annotationValue.annotation(), classLoader);
8888
}
8989
case AnnotationValue.OfClass classValue -> {
90-
return loadClass(classValue.className().stringValue(), classLoader);
90+
return fromTypeDescriptor(classValue.className().stringValue());
9191
}
9292
case AnnotationValue.OfEnum enumValue -> {
9393
return parseEnum(enumValue, classLoader);
@@ -105,13 +105,8 @@ private static String fromTypeDescriptor(String descriptor) {
105105
}
106106

107107
private static Class<?> loadClass(String className, @Nullable ClassLoader classLoader) {
108-
try {
109-
String name = fromTypeDescriptor(className);
110-
return ClassUtils.forName(name, classLoader);
111-
}
112-
catch (ClassNotFoundException ex) {
113-
return Object.class;
114-
}
108+
String name = fromTypeDescriptor(className);
109+
return ClassUtils.resolveClassName(name, classLoader);
115110
}
116111

117112
private static Object parseArrayValue(String className, @Nullable ClassLoader classLoader, AnnotationValue.OfArray arrayValue) {
@@ -160,7 +155,7 @@ private static Class<?> resolveArrayElementType(List<AnnotationValue> values, @N
160155
return MergedAnnotation.class;
161156
}
162157
case AnnotationValue.OfClass _ -> {
163-
return Class.class;
158+
return String.class;
164159
}
165160
case AnnotationValue.OfEnum enumValue -> {
166161
return loadClass(enumValue.className().stringValue(), classLoader);

spring-core/src/test/java/org/springframework/core/type/classreading/DefaultAnnotationMetadataTests.java

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,26 @@
1616

1717
package org.springframework.core.type.classreading;
1818

19+
import java.io.IOException;
20+
import java.lang.annotation.Retention;
21+
import java.lang.annotation.RetentionPolicy;
22+
23+
import com.github.benmanes.caffeine.cache.Caffeine;
24+
import org.junit.jupiter.api.Test;
25+
1926
import org.springframework.core.type.AbstractAnnotationMetadataTests;
2027
import org.springframework.core.type.AnnotationMetadata;
2128

29+
import static org.assertj.core.api.Assertions.assertThat;
30+
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
31+
2232
/**
2333
* Tests for {@link SimpleAnnotationMetadata} and
2434
* {@link SimpleAnnotationMetadataReadingVisitor} on Java < 24,
2535
* and for the ClassFile API variant on Java >= 24.
2636
*
2737
* @author Phillip Webb
38+
* @author Brian Clozel
2839
*/
2940
class DefaultAnnotationMetadataTests extends AbstractAnnotationMetadataTests {
3041

@@ -34,9 +45,25 @@ protected AnnotationMetadata get(Class<?> source) {
3445
return MetadataReaderFactory.create(source.getClassLoader())
3546
.getMetadataReader(source.getName()).getAnnotationMetadata();
3647
}
37-
catch (Exception ex) {
48+
catch (IOException ex) {
3849
throw new IllegalStateException(ex);
3950
}
4051
}
4152

53+
@Test
54+
void getClassAttributeWhenUnknownClass() {
55+
var annotation = get(WithClassMissingFromClasspath.class).getAnnotations().get(ClassAttributes.class);
56+
assertThat(annotation.getStringArray("types")).contains("com.github.benmanes.caffeine.cache.Caffeine");
57+
assertThatIllegalArgumentException().isThrownBy(() -> annotation.getClassArray("types"));
58+
}
59+
60+
@ClassAttributes(types = {Caffeine.class})
61+
public static class WithClassMissingFromClasspath {
62+
}
63+
64+
@Retention(RetentionPolicy.RUNTIME)
65+
public @interface ClassAttributes {
66+
Class<?>[] types();
67+
}
68+
4269
}

spring-core/src/test/java/org/springframework/core/type/classreading/SimpleAnnotationMetadataTests.java

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,25 @@
1616

1717
package org.springframework.core.type.classreading;
1818

19+
import java.io.IOException;
20+
import java.lang.annotation.Retention;
21+
import java.lang.annotation.RetentionPolicy;
22+
23+
import com.github.benmanes.caffeine.cache.Caffeine;
24+
import org.junit.jupiter.api.Test;
25+
1926
import org.springframework.core.type.AbstractAnnotationMetadataTests;
2027
import org.springframework.core.type.AnnotationMetadata;
2128

29+
import static org.assertj.core.api.Assertions.assertThat;
30+
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
31+
2232
/**
2333
* Tests for {@link SimpleAnnotationMetadata} and
2434
* {@link SimpleAnnotationMetadataReadingVisitor}.
2535
*
2636
* @author Phillip Webb
37+
* @author Brian Clozel
2738
*/
2839
class SimpleAnnotationMetadataTests extends AbstractAnnotationMetadataTests {
2940

@@ -34,9 +45,26 @@ protected AnnotationMetadata get(Class<?> source) {
3445
source.getClassLoader()).getMetadataReader(
3546
source.getName()).getAnnotationMetadata();
3647
}
37-
catch (Exception ex) {
48+
catch (IOException ex) {
3849
throw new IllegalStateException(ex);
3950
}
4051
}
4152

53+
@Test
54+
void getClassAttributeWhenUnknownClass() {
55+
var annotation = get(WithClassMissingFromClasspath.class).getAnnotations().get(ClassAttributes.class);
56+
assertThat(annotation.getStringArray("types")).contains("com.github.benmanes.caffeine.cache.Caffeine");
57+
assertThatIllegalArgumentException().isThrownBy(() -> annotation.getClassArray("types"));
58+
}
59+
60+
@ClassAttributes(types = {Caffeine.class})
61+
public static class WithClassMissingFromClasspath {
62+
}
63+
64+
65+
@Retention(RetentionPolicy.RUNTIME)
66+
public @interface ClassAttributes {
67+
Class<?>[] types();
68+
}
69+
4270
}

0 commit comments

Comments
 (0)