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

Annotation attributes not available at runtime #535

Closed
dsyer opened this issue Jul 9, 2018 · 4 comments
Closed

Annotation attributes not available at runtime #535

dsyer opened this issue Jul 9, 2018 · 4 comments
Assignees
Labels
native-image spring spring related issue

Comments

@dsyer
Copy link

dsyer commented Jul 9, 2018

Spring has a bunch of use cases for annotations and quite a rich set of convenience classes for introspecting them. They don't seem to fail, much, at runtime in a native image, but they don't actually work either.

Example code:

public class Annotations {

	@Autowired(required = false)
	public void setConverters(List<Bar> converters) {
	}

	public static void main(String[] args) throws Exception {
		new Annotations().run();
	}

	private void run() throws Exception {
		Method method = getClass().getMethod("setConverters", List.class);
		Autowired ann = method.getAnnotation(Autowired.class);
		AnnotationAttributes attributes = AnnotatedElementUtils
				.getMergedAnnotationAttributes(method, Autowired.class);
		// Null in native image, {required=false} in normal JDK
		System.err.println(attributes);

		// Boom! Blows up in native image, {required=false} in normal JDK
		// System.err.println(AnnotationUtils.getAnnotationAttributes(ann, true));
	}
}

I have tried to isolate the failure to specific reflective access to the annotation, but haven't been successful. Once (only) I saw some logs from the call to AnnotatedElementUtils:

Jul 09, 2018 8:51:29 AM org.springframework.core.annotation.AnnotationUtils handleIntrospectionFailure
INFO: Failed to introspect annotations on public void Annotations.setConverters(java.util.List): java.lang.IllegalStateException: Could not obtain annotation attribute value for public abstract boolean org.springframework.beans.factory.annotation.Autowired.required()

The fact that I only saw this once suggests there is perhaps another issue lurking to do with log configuration (Spring uses commons-logging which defaults to java.util.logging if nothing else is available).

@cstancu
Copy link
Member

cstancu commented Jul 9, 2018

Thank you for reporting! Do you have a repo that we can use to easily replicate this?

@dsyer
Copy link
Author

dsyer commented Jul 9, 2018

The code above will compile and run with just spring-beans (and spring-core which is transitive) on the class path.

@dsyer
Copy link
Author

dsyer commented Apr 1, 2019

FWIW I think this is a duplicate of #999.

@farquet farquet added the spring spring related issue label Mar 13, 2020
@sbrannen
Copy link

I just verified that the following (modified version of the sample application) passes in the spring-core native image tests build against GraalVM 20.0.

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;
import java.util.List;

import org.junit.jupiter.api.Test;

import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.annotation.AnnotationUtils;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.entry;

public class AnnotationsTests {

	@Test
	void test() throws Exception {
		Method method = getClass().getMethod("setConverters", List.class);
		AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(method, Autowired.class);
		assertThat(attributes).containsExactly(entry("required", false));

		Autowired ann = method.getAnnotation(Autowired.class);
		assertThat(AnnotationUtils.getAnnotationAttributes(ann, true)).containsExactly(entry("required", false));
	}

	@Autowired(required = false)
	public void setConverters(List<Bar> converters) {
	}


	@Retention(RetentionPolicy.RUNTIME)
	@interface Autowired {

		boolean required() default true;
	}

	static class Bar {
	}

}

Thus, feel free to close this issue.

@eginez eginez closed this as completed Apr 16, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
native-image spring spring related issue
Projects
None yet
Development

No branches or pull requests

6 participants