Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exception with Spring Framework 5.2 merged annotations mechanism #1170

Closed
sdeleuze opened this issue Apr 16, 2019 · 4 comments
Closed

Exception with Spring Framework 5.2 merged annotations mechanism #1170

sdeleuze opened this issue Apr 16, 2019 · 4 comments
Assignees

Comments

@sdeleuze
Copy link
Collaborator

sdeleuze commented Apr 16, 2019

Spring Fu native image builds are broken (with GraalVM RC14 and RC15 so it is not a regression unlike what I wrote in the original report). It seems it comes from the new merged annotation subsystem that was introduced as part of Spring Framework 5.2 M1 which SubstrateVM seems not supporting.

The error can be observed when running the native image of our basic jafu-reactive-minimal sample and generates this stack trace:

Exception in thread "main" java.util.NoSuchElementException: No attribute named 'value' present in merged annotation org.springframework.core.annotation.Order
	at org.springframework.core.annotation.AbstractMergedAnnotation.getRequiredAttributeValue(AbstractMergedAnnotation.java:198)
	at org.springframework.core.annotation.AbstractMergedAnnotation.getInt(AbstractMergedAnnotation.java:90)
	at org.springframework.core.annotation.OrderUtils.findOrder(OrderUtils.java:113)
	at org.springframework.core.annotation.OrderUtils.getOrderFromAnnotations(OrderUtils.java:104)
	at org.springframework.core.annotation.AnnotationAwareOrderComparator.findOrderFromAnnotation(AnnotationAwareOrderComparator.java:75)
	at org.springframework.core.annotation.AnnotationAwareOrderComparator.findOrder(AnnotationAwareOrderComparator.java:68)
	at org.springframework.core.OrderComparator.getOrder(OrderComparator.java:124)
	at org.springframework.core.OrderComparator.getOrder(OrderComparator.java:112)
	at org.springframework.core.OrderComparator.doCompare(OrderComparator.java:81)
	at org.springframework.core.OrderComparator.compare(OrderComparator.java:68)
	at java.util.TimSort.binarySort(TimSort.java:296)
	at java.util.TimSort.sort(TimSort.java:221)
	at java.util.Arrays.sort(Arrays.java:1512)
	at java.util.ArrayList.sort(ArrayList.java:1462)
	at org.springframework.core.annotation.AnnotationAwareOrderComparator.sort(AnnotationAwareOrderComparator.java:111)
	at org.springframework.boot.SpringApplication.getSpringFactoriesInstances(SpringApplication.java:438)
	at org.springframework.boot.SpringApplication.getSpringFactoriesInstances(SpringApplication.java:427)
	at org.springframework.boot.SpringApplication.<init>(SpringApplication.java:273)
	at org.springframework.boot.SpringApplication.<init>(SpringApplication.java:252)
	at org.springframework.fu.jafu.JafuApplication$1.<init>(JafuApplication.java:73)
	at org.springframework.fu.jafu.JafuApplication.run(JafuApplication.java:73)
	at org.springframework.fu.jafu.JafuApplication.run(JafuApplication.java:60)
	at com.sample.Application.main(Application.java:30)

To reproduce:

git clone https://github.com/spring-projects/spring-fu.git
./gradlew clean build publishToMavenLocal
cd samples/jafu-reactive-minimal/
./build.sh
./com.sample.application
@sdeleuze sdeleuze changed the title Regression in Spring Fu with rc15 Exeption in Spring Fu application with GraalVM rc15 Apr 16, 2019
@cstancu
Copy link
Member

cstancu commented Apr 16, 2019

@sdeleuze how does spring access the value attribute for annotations. Is it via reflection? I quickly looked in the implementation of AbstractMergedAnnotation.getAttributeValue but couldn't immediately figure it out.

@philwebb
Copy link

@cstancu It's usually via reflection, but there's an additional layer of indirection so that we can use the same API against different underlying data structures. The TypeMappedAnnotation class has the following member variable:

 BiFunction<Method, Object, Object> valueExtractor;

Most of the time, this will be a method reference to ReflectionUtils::invokeMethod which ultimately calls Method.invoke. My guess is this extra indirection means GraalVM doesn't realize that there is a reflective call going on.

@cstancu
Copy link
Member

cstancu commented Apr 19, 2019

@philwebb the indirection that you mention above is not the problem. After some debugging I found that you are calling annotationType.getDeclaredMethods() where the annotationType comes from a call to annotation.annotationType(), so it looks like you need to register the annotation interface methods for reflection, at least for those annotations whose internals you expect to access via reflection. By adding this reflection configuration this problem goes away:

{
    "name": "org.springframework.core.annotation.Order",
    "allDeclaredMethods": true
}

To automate registering annotation interface methods for reflection you can write a Feature to detect all annotation interfaces that need reflective access.

However, now I hit #1135. I will work on that next.

@cstancu cstancu closed this as completed Apr 19, 2019
@cstancu
Copy link
Member

cstancu commented Apr 19, 2019

FYI #1135 is now fixed.

@sdeleuze sdeleuze changed the title Exeption in Spring Fu application with GraalVM rc15 Exception in Spring Fu application with GraalVM rc15 Apr 23, 2019
@sdeleuze sdeleuze changed the title Exception in Spring Fu application with GraalVM rc15 Exception with Spring Framework 5.2 merged annotations mechanism Apr 23, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants