Java version: 25.0.2
Spring version: 7.0.8
I am currently migrating one of my employer's applications to spring-boot 4, thereby over to spring-core 7.0.8, when I run in to the following regression:
Whenever their code attempts to load some byte array metadata from some annotation using spring-core's MetadataReader, it fails, where the same code has worked perfectly before.
Example code:
package com;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
@Example.TestAnnotation({1, 2, 3})
public class Example {
@Retention(RetentionPolicy.RUNTIME)
@interface TestAnnotation {
byte[] value();
}
static void main() throws Exception {
var factory = MetadataReaderFactory.create(Example.class.getClassLoader());
var reader = factory.getMetadataReader(Example.class.getName());
var mergedAnnotation = reader.getAnnotationMetadata()
.getAnnotations()
.get(TestAnnotation.class);
byte[] expected = {1, 2, 3};
/* Either:
var actual = mergedAnnotation.synthesize().value();
/*/// Alternatively:
var actual = mergedAnnotation.getByteArray("value");
//*/
// Never reached, above always throws IllegalStateException
assert Arrays.equals(actual, expected);
}
}
Expected outcome:
- The program runs to completion
Actual outcome:
Exception in thread "main" java.lang.IllegalStateException: Attribute 'value' in annotation com.Example$TestAnnotation should be compatible with [B but a [Ljava.lang.Byte; value was returned
at org.springframework.core.annotation.TypeMappedAnnotation.adaptForAttribute(TypeMappedAnnotation.java:518)
at org.springframework.core.annotation.TypeMappedAnnotation.adapt(TypeMappedAnnotation.java:447)
at org.springframework.core.annotation.TypeMappedAnnotation.getValue(TypeMappedAnnotation.java:398)
at org.springframework.core.annotation.TypeMappedAnnotation.getAttributeValue(TypeMappedAnnotation.java:380)
at org.springframework.core.annotation.AbstractMergedAnnotation.getRequiredAttributeValue(AbstractMergedAnnotation.java:215)
at org.springframework.core.annotation.AbstractMergedAnnotation.getByteArray(AbstractMergedAnnotation.java:63)
at com.Example.main(Example.java:26)
To get my employer's application back up and running, I've come up with the following:
byte[] actual;
try {
var source = mergedAnnotation.getSource();
var accessor = source.getClass().getDeclaredMethod("annotation");
accessor.setAccessible(true);
var annotation = (Annotation) accessor.invoke(source);
var data = (AnnotationValue.OfArray) annotation.elements().stream()
.filter(element -> element.name().equalsString("value"))
.map(AnnotationElement::value)
.findAny()
.orElseThrow();
actual = new byte[data.values().size()];
for (int i = 0; i < data.values().size(); i++) {
actual[i] = ((AnnotationValue.OfByte)data.values().get(i)).byteValue();
}
} catch (Exception ex) {
throw new IllegalStateException("Failed to reflectively read annotation data", ex);
}
But as you can imagine, I'm very much looking forward to a less hair raising fix from You.
Java version: 25.0.2
Spring version: 7.0.8
I am currently migrating one of my employer's applications to spring-boot 4, thereby over to spring-core 7.0.8, when I run in to the following regression:
Whenever their code attempts to load some byte array metadata from some annotation using spring-core's
MetadataReader, it fails, where the same code has worked perfectly before.Example code:
Expected outcome:
Actual outcome:
To get my employer's application back up and running, I've come up with the following:
But as you can imagine, I'm very much looking forward to a less hair raising fix from You.