Browse Source

Do not load concrete types in annotation metadata

This change fixes a regression introduced in the previous commit.

Closes gh-35252
pull/35392/head
Brian Clozel 4 months ago
parent
commit
81b4020fc6
  1. 1
      spring-core/spring-core.gradle
  2. 13
      spring-core/src/main/java24/org/springframework/core/type/classreading/ClassFileAnnotationMetadata.java
  3. 29
      spring-core/src/test/java/org/springframework/core/type/classreading/DefaultAnnotationMetadataTests.java
  4. 30
      spring-core/src/test/java/org/springframework/core/type/classreading/SimpleAnnotationMetadataTests.java

1
spring-core/spring-core.gradle

@ -88,6 +88,7 @@ dependencies { @@ -88,6 +88,7 @@ dependencies {
optional("org.jetbrains.kotlin:kotlin-stdlib")
optional("org.jetbrains.kotlinx:kotlinx-coroutines-core")
optional("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
testCompileOnly("com.github.ben-manes.caffeine:caffeine")
testFixturesImplementation("io.projectreactor:reactor-test")
testFixturesImplementation("org.assertj:assertj-core")
testFixturesImplementation("org.junit.jupiter:junit-jupiter")

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

@ -87,7 +87,7 @@ abstract class ClassFileAnnotationMetadata { @@ -87,7 +87,7 @@ abstract class ClassFileAnnotationMetadata {
return createMergedAnnotation(className, annotationValue.annotation(), classLoader);
}
case AnnotationValue.OfClass classValue -> {
return loadClass(classValue.className().stringValue(), classLoader);
return fromTypeDescriptor(classValue.className().stringValue());
}
case AnnotationValue.OfEnum enumValue -> {
return parseEnum(enumValue, classLoader);
@ -105,13 +105,8 @@ abstract class ClassFileAnnotationMetadata { @@ -105,13 +105,8 @@ abstract class ClassFileAnnotationMetadata {
}
private static Class<?> loadClass(String className, @Nullable ClassLoader classLoader) {
try {
String name = fromTypeDescriptor(className);
return ClassUtils.forName(name, classLoader);
}
catch (ClassNotFoundException ex) {
return Object.class;
}
String name = fromTypeDescriptor(className);
return ClassUtils.resolveClassName(name, classLoader);
}
private static Object parseArrayValue(String className, @Nullable ClassLoader classLoader, AnnotationValue.OfArray arrayValue) {
@ -160,7 +155,7 @@ abstract class ClassFileAnnotationMetadata { @@ -160,7 +155,7 @@ abstract class ClassFileAnnotationMetadata {
return MergedAnnotation.class;
}
case AnnotationValue.OfClass _ -> {
return Class.class;
return String.class;
}
case AnnotationValue.OfEnum enumValue -> {
return loadClass(enumValue.className().stringValue(), classLoader);

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

@ -16,15 +16,26 @@ @@ -16,15 +16,26 @@
package org.springframework.core.type.classreading;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.junit.jupiter.api.Test;
import org.springframework.core.type.AbstractAnnotationMetadataTests;
import org.springframework.core.type.AnnotationMetadata;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
/**
* Tests for {@link SimpleAnnotationMetadata} and
* {@link SimpleAnnotationMetadataReadingVisitor} on Java < 24,
* and for the ClassFile API variant on Java >= 24.
*
* @author Phillip Webb
* @author Brian Clozel
*/
class DefaultAnnotationMetadataTests extends AbstractAnnotationMetadataTests {
@ -34,9 +45,25 @@ class DefaultAnnotationMetadataTests extends AbstractAnnotationMetadataTests { @@ -34,9 +45,25 @@ class DefaultAnnotationMetadataTests extends AbstractAnnotationMetadataTests {
return MetadataReaderFactory.create(source.getClassLoader())
.getMetadataReader(source.getName()).getAnnotationMetadata();
}
catch (Exception ex) {
catch (IOException ex) {
throw new IllegalStateException(ex);
}
}
@Test
void getClassAttributeWhenUnknownClass() {
var annotation = get(WithClassMissingFromClasspath.class).getAnnotations().get(ClassAttributes.class);
assertThat(annotation.getStringArray("types")).contains("com.github.benmanes.caffeine.cache.Caffeine");
assertThatIllegalArgumentException().isThrownBy(() -> annotation.getClassArray("types"));
}
@ClassAttributes(types = {Caffeine.class})
public static class WithClassMissingFromClasspath {
}
@Retention(RetentionPolicy.RUNTIME)
public @interface ClassAttributes {
Class<?>[] types();
}
}

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

@ -16,14 +16,25 @@ @@ -16,14 +16,25 @@
package org.springframework.core.type.classreading;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.junit.jupiter.api.Test;
import org.springframework.core.type.AbstractAnnotationMetadataTests;
import org.springframework.core.type.AnnotationMetadata;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
/**
* Tests for {@link SimpleAnnotationMetadata} and
* {@link SimpleAnnotationMetadataReadingVisitor}.
*
* @author Phillip Webb
* @author Brian Clozel
*/
class SimpleAnnotationMetadataTests extends AbstractAnnotationMetadataTests {
@ -34,9 +45,26 @@ class SimpleAnnotationMetadataTests extends AbstractAnnotationMetadataTests { @@ -34,9 +45,26 @@ class SimpleAnnotationMetadataTests extends AbstractAnnotationMetadataTests {
source.getClassLoader()).getMetadataReader(
source.getName()).getAnnotationMetadata();
}
catch (Exception ex) {
catch (IOException ex) {
throw new IllegalStateException(ex);
}
}
@Test
void getClassAttributeWhenUnknownClass() {
var annotation = get(WithClassMissingFromClasspath.class).getAnnotations().get(ClassAttributes.class);
assertThat(annotation.getStringArray("types")).contains("com.github.benmanes.caffeine.cache.Caffeine");
assertThatIllegalArgumentException().isThrownBy(() -> annotation.getClassArray("types"));
}
@ClassAttributes(types = {Caffeine.class})
public static class WithClassMissingFromClasspath {
}
@Retention(RetentionPolicy.RUNTIME)
public @interface ClassAttributes {
Class<?>[] types();
}
}

Loading…
Cancel
Save