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

Discovery of annotated type parameter doesn't work #3671

Closed
ericbottard opened this issue Aug 12, 2021 · 21 comments
Closed

Discovery of annotated type parameter doesn't work #3671

ericbottard opened this issue Aug 12, 2021 · 21 comments
Assignees
Labels
bug spring spring related issue

Comments

@ericbottard
Copy link

ericbottard commented Aug 12, 2021

Describe the issue
Code that tries to access annotations on type parameters currently fails at runtime with an NPE:

Exception in thread "main" java.lang.NullPointerException
	at sun.reflect.annotation.TypeAnnotationParser.mapTypeAnnotations(TypeAnnotationParser.java:385)
	at sun.reflect.annotation.AnnotatedTypeFactory$AnnotatedTypeBaseImpl.<init>(AnnotatedTypeFactory.java:153)
	at sun.reflect.annotation.AnnotatedTypeFactory.buildAnnotatedType(AnnotatedTypeFactory.java:68)
	at sun.reflect.annotation.AnnotatedTypeFactory$AnnotatedParameterizedTypeImpl.getAnnotatedActualTypeArguments(AnnotatedTypeFactory.java:434)
	at sun.reflect.annotation.AnnotatedTypeFactory$AnnotatedParameterizedTypeImpl.toString(AnnotatedTypeFactory.java:476)
	at java.lang.String.valueOf(String.java:3365)
	at java.io.PrintStream.println(PrintStream.java:1047)
	at com.acme.Exhibit.main(Exhibit.java:18)

The above is from the sample program below, which works fine when run as a regular java program.

Moreover, this still fails after trying to re-compile it natively with hints created by the agent (it doesn't capture much, only the following:)

reflect-config.json

[
{
  "name":"com.acme.Exhibit",
  "fields":[{"name":"strings"}]
}
]

Steps to reproduce the issue
This small program reproduces the issue:

public class Exhibit {

	private List<@Funny String> strings = new ArrayList<>();

	public static void main(String[] args) throws Exception {
		Exhibit e = new Exhibit();
		final Field field = e.getClass().getDeclaredField("strings");

		// Expected output:   java.util.List<@com.acme.Exhibit$Funny() java.lang.String>
		System.out.println(field.getAnnotatedType());
	}

	@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
	@Retention(RUNTIME)
	@Documented
	static @interface Funny {

	}
}

Describe GraalVM and your environment:
GraalVM 21.2.0 on Mac OS:

java -version
openjdk version "16.0.2" 2021-07-20
OpenJDK Runtime Environment GraalVM CE 21.2.0 (build 16.0.2+7-jvmci-21.2-b08)
OpenJDK 64-Bit Server VM GraalVM CE 21.2.0 (build 16.0.2+7-jvmci-21.2-b08, mixed mode, sharing)


More details
This issue is not as "corner case" as it may seem, as this is a typical usage pattern when using bean validation (jsr 380).

@kdvolder
Copy link

@ericbottard example didn't reproduce the NPE for me. I noted a difference in the output though.

Instead of:

java.util.List<@com.acme.Exhibit$Funny() java.lang.String>

When I run the sample it instead prints:

sun.reflect.annotation.AnnotatedTypeFactory$AnnotatedParameterizedTypeImpl@5a42bbf4

Probably due to me using a different Graal JVM version:

$ java -version 
openjdk version "11.0.12" 2021-07-20
OpenJDK Runtime Environment GraalVM CE 21.2.0 (build 11.0.12+6-jvmci-21.2-b08)
OpenJDK 64-Bit Server VM GraalVM CE 21.2.0 (build 11.0.12+6-jvmci-21.2-b08, mixed mode, sharing)

Modifying the example slightly I was still able to reproduce the bug however. It just requires that we try to explicitly pry the information in the AnnotatedParameterizedType apart.

I added this to the sample code:

		AnnotatedParameterizedType at = (AnnotatedParameterizedType) field.getAnnotatedType();
		System.out.println("at = " + at);
		List<Annotation> annots = Arrays.asList(at.getAnnotations());
		System.out.println("annots = " + annots);
		List<AnnotatedType> typeArgs = Arrays.asList(at.getAnnotatedActualTypeArguments());
		System.out.println("typeArgs = " + typeArgs);
		for (AnnotatedType typeArg : typeArgs) {
			List<Annotation> typeArgAnnots = Arrays.asList(typeArg.getAnnotations());
			System.out.println("typeArgAnnots = " + typeArgAnnots);
		}

And it produces an NPE when calling at.getAnnotatedActualTypeArguments():

Exception in thread "main" java.lang.NullPointerException
	at sun.reflect.annotation.TypeAnnotationParser.mapTypeAnnotations(TypeAnnotationParser.java:378)
	at sun.reflect.annotation.AnnotatedTypeFactory$AnnotatedTypeBaseImpl.<init>(AnnotatedTypeFactory.java:140)
	at sun.reflect.annotation.AnnotatedTypeFactory.buildAnnotatedType(AnnotatedTypeFactory.java:64)
	at sun.reflect.annotation.AnnotatedTypeFactory$AnnotatedParameterizedTypeImpl.getAnnotatedActualTypeArguments(AnnotatedTypeFactory.java:291)
	at com.acme.Exhibit.main(Exhibit.java:45)

@kdvolder
Copy link

kdvolder commented Aug 12, 2021

I was able to get the example working by adding some stuff to reflect-config.json:

{
	"name": "com.acme.Exhibit$Funny",
    "allDeclaredConstructors" : true,
    "allPublicConstructors" : true,
    "allDeclaredMethods" : true,
    "allPublicMethods" : true,
    "allDeclaredClasses" : true,
    "allPublicClasses" : true
},
{
	"name": "sun.reflect.annotation.AnnotationType",
    "allDeclaredConstructors" : true,
    "allPublicConstructors" : true,
    "allDeclaredMethods" : true,
    "allPublicMethods" : true,
    "allDeclaredClasses" : true,
    "allPublicClasses" : true
}

The rest of the json files were left unchanged (i.e. as generated by the java tracing agent).

Just adding the Exhibit$Funny type alone wasn't sufficient. On a hunch I also added sun.reflect.annotation.AnnotationType as the location of the NPE in code was trying to read 'retention' info and it is stored as a field in that type. This was really a totally wild guess on my part and I was actually somewhat surprised that it works.

Not sure what it means for this bug report. Is it expected to behave this way? (I'm inclined to say, even though I got it working, it should still be considered as a failing/bug of the tracing agent, since it is producing incomplete info in reflect-config.json).

@munishchouhan
Copy link
Contributor

@ericbottard does the solution provided by @kdvolder solved your issue?

@munishchouhan munishchouhan self-assigned this Aug 16, 2021
@ericbottard
Copy link
Author

Sadly it did not (it does solve the issue with the simple testcase I came up with above, but does not solve the real-life usecase we're encountering). Let me try to complexify the testcase a bit (involving Hibernate Validator)

@ericbottard
Copy link
Author

Sooo... The following more involved testcase

public class Exhibit {

	private List<@NotBlank String> strings = List.of("hello", "");

	public static void main(String[] args) throws Exception {
		Exhibit e = new Exhibit();
		ValidatorFactory factory = Validation.byDefaultProvider().configure()
				.messageInterpolator(new ParameterMessageInterpolator()).buildValidatorFactory();

		Validator validator = factory.getValidator();
		final Set<ConstraintViolation<Exhibit>> violations = validator.validate(e);
		System.out.println(violations);
	}

}

works* with native compilation, using what is captured by the agent (nothing extraordinary jumps at me there) BUT prints the following message:

Warning: Image 'native-playground' is a fallback image that requires a JDK for execution (use --no-fallback to suppress fallback image generation and to print more detailed information why a fallback image was necessary).

Re-compiling with --no-fallback yields errors related to UnresolvedElementException: Discovered unresolved method/type during parsing which AFAIU are unrelated and that I can sweep under the rug with --allow-incomplete-classpath. This then brings us back to the original NPE when I try to run the image (this is WITHOUT the hints that @kdvolder suggested).

Adding what he suggested (about sun.reflect.annotation.AnnotationType) produces a new error at compile time, which may be a good lead:

Error: Unsupported features in 2 methods
Detailed message:
Error: com.oracle.svm.hosted.substitute.DeletedElementException: Unsupported method java.lang.Class.getConstantPool() is reachable: The declaring class of this element has been substituted, but this element is not present in the substitution class
To diagnose the issue, you can add the option --report-unsupported-elements-at-runtime. The unsupported element is then reported at run time when it is accessed the first time.
Trace:
	at parsing java.lang.System$2.getConstantPool(System.java:2148)
Call path from entry point to java.lang.System$2.getConstantPool(Class):
	at java.lang.System$2.getConstantPool(System.java:2148)
	at sun.reflect.annotation.AnnotationType.<init>(AnnotationType.java:147)
	at com.oracle.svm.reflect.AnnotationType_constructor_a12aac709c5b73485f8b6cd2cb339d1846eb3a09_50.newInstance(Unknown Source)
	at java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:480)
	at java.util.ServiceLoader$ProviderImpl.newInstance(ServiceLoader.java:780)
	at java.util.ServiceLoader$ProviderImpl.get(ServiceLoader.java:722)
	at com.oracle.svm.core.jdk.SystemPropertiesSupport.initializeLazyValue(SystemPropertiesSupport.java:216)
	at com.oracle.svm.core.jdk.SystemPropertiesSupport.getProperty(SystemPropertiesSupport.java:169)
	at com.oracle.svm.core.jdk.Target_java_lang_System.getProperty(JavaLangSubstitutions.java:290)
	at com.oracle.svm.jni.JNIJavaCallWrappers.jniInvoke_VARARGS:Ljava_lang_System_2_0002egetProperty_00028Ljava_lang_String_2_00029Ljava_lang_String_2(generated:0)
Error: com.oracle.svm.hosted.substitute.DeletedElementException: Unsupported method java.lang.Class.getRawAnnotations() is reachable: The declaring class of this element has been substituted, but this element is not present in the substitution class
To diagnose the issue, you can add the option --report-unsupported-elements-at-runtime. The unsupported element is then reported at run time when it is accessed the first time.
Trace:
	at parsing java.lang.System$2.getRawClassAnnotations(System.java:2160)
Call path from entry point to java.lang.System$2.getRawClassAnnotations(Class):
	at java.lang.System$2.getRawClassAnnotations(System.java:2160)
	at sun.reflect.annotation.AnnotationType.<init>(AnnotationType.java:146)
	at com.oracle.svm.reflect.AnnotationType_constructor_a12aac709c5b73485f8b6cd2cb339d1846eb3a09_50.newInstance(Unknown Source)
	at java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:480)
	at java.util.ServiceLoader$ProviderImpl.newInstance(ServiceLoader.java:780)
	at java.util.ServiceLoader$ProviderImpl.get(ServiceLoader.java:722)
	at com.oracle.svm.core.jdk.SystemPropertiesSupport.initializeLazyValue(SystemPropertiesSupport.java:216)
	at com.oracle.svm.core.jdk.SystemPropertiesSupport.getProperty(SystemPropertiesSupport.java:169)
	at com.oracle.svm.core.jdk.Target_java_lang_System.getProperty(JavaLangSubstitutions.java:290)
	at com.oracle.svm.jni.JNIJavaCallWrappers.jniInvoke_VARARGS:Ljava_lang_System_2_0002egetProperty_00028Ljava_lang_String_2_00029Ljava_lang_String_2(generated:0)

So, to recap:

  • very simple example (the one from my original report), when adding hints about the annotation itself (com.acme.Exhibit$Funny) and sun.reflect.annotation.AnnotationType as suggested here works
  • the more real-world scenario, involving hibernate validator (reproduced above in this very comment) does not work (uses a fallback image)
  • that same example, when using the hint for sun.reflect.annotation.AnnotationType PLUS --no-fallback --allow-incomplete-classpath point towards java.lang.System$2.getRawClassAnnotations and java.lang.System$2.getConstantPool

@munishchouhan
Copy link
Contributor

@ericbottard Please add --report-unsupported-elements-at-runtime and try again

@ericbottard
Copy link
Author

Did that already, which results in the NPE at runtime with no extra info. This is why I focused on reporting about getRawClassAnnotations() and getConstantPool() which I thought were the "cause", but I must confess I don't understand everything at play here. In particular, I'm not sure we're not too agressive with what we put in reflect-config.json (using all*: true) and creating more issues as a result of that.

@munishchouhan
Copy link
Contributor

@ericbottard please check out this issue, where this error has been fixed
#2736
and please provide a working reproducer or GitHub repo link with execution steps

@kdvolder
Copy link

kdvolder commented Aug 23, 2021

@mcraj017 For context, Eric and I are working together on this (trying to get past that error in our project).

I've taken a look at #2736 but I'm not sure how it helps. Did I understand correctly that its telling us that if we add --report-unsupported-elements-at-runtime this should 'fix' it? But we are already using that option. And indeed, with that option there is no com.oracle.svm.hosted.substitute.DeletedElementException: Unsupported method... error. However we are then back to the familiar NPE when hibernate is trying to access reflective info on type annotations.

Eric's more elaborate example isn't solved by the extra json config. Perhaps there's other extra reflection config that could be added to make it work but we are unsure how to figure out what extra things we could try to add.

and please provide a working reproducer or GitHub repo link with execution steps

Sure, will do. I'm repackaging Eric's more complex example at the moment to make it publically available somewhere. I'll provide a link shortly.

@kdvolder
Copy link

Sample project:
graal-bug-3671.zip

To reproduce see the build-and-run-native.sh script. You can inspect it to see the exact steps taken. If you want to run that script yourself you'll probably need to modify this bit:

export JAVA_HOME=/home/kdvolder/Applications/graalvm-ce-java11-21.2.0

... to point to where you have graalvm installed.

For reference here's the full output I get running that script:

$ ./build-and-run-native.sh 
OpenJDK 64-Bit Server VM warning: Ignoring option MaxPermSize; support was removed in 8.0
[INFO] Scanning for projects...
[INFO] 
[INFO] -----------< com.vmware.tanzu.accelerator:native-playground >-----------
[INFO] Building App Accelerator :: Native Playground 0.2.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-resources-plugin:3.2.0:resources (default-resources) @ native-playground ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Using 'UTF-8' encoding to copy filtered properties files.
[INFO] Copying 0 resource
[INFO] Copying 7 resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ native-playground ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-resources-plugin:3.2.0:testResources (default-testResources) @ native-playground ---
[INFO] Not copying test resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ native-playground ---
[INFO] Not compiling test sources
[INFO] 
[INFO] --- maven-surefire-plugin:2.22.2:test (default-test) @ native-playground ---
[INFO] Tests are skipped.
[INFO] 
[INFO] --- maven-jar-plugin:3.2.0:jar (default-jar) @ native-playground ---
[INFO] Building jar: /home/kdvolder/tmp/graal/graal-bug-3671/target/native-playground-0.2.0-SNAPSHOT.jar
[INFO] 
[INFO] --- spring-boot-maven-plugin:2.5.4:repackage (repackage) @ native-playground ---
[INFO] Attaching repackaged archive /home/kdvolder/tmp/graal/graal-bug-3671/target/native-playground-0.2.0-SNAPSHOT-exec.jar with classifier exec
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  1.236 s
[INFO] Finished at: 2021-08-23T14:55:25-07:00
[INFO] ------------------------------------------------------------------------
Aug. 23, 2021 2:55:25 P.M. org.hibernate.validator.internal.util.Version <clinit>
INFO: HV000001: Hibernate Validator 6.1.7.Final
[ConstraintViolationImpl{interpolatedMessage='must not be blank', propertyPath=strings[1].<list element>, rootBeanClass=class com.acme.Exhibit, messageTemplate='{javax.validation.constraints.NotBlank.message}'}]
OpenJDK 64-Bit Server VM warning: Ignoring option MaxPermSize; support was removed in 8.0
[INFO] Scanning for projects...
[INFO] 
[INFO] -----------< com.vmware.tanzu.accelerator:native-playground >-----------
[INFO] Building App Accelerator :: Native Playground 0.2.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-resources-plugin:3.2.0:resources (default-resources) @ native-playground ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Using 'UTF-8' encoding to copy filtered properties files.
[INFO] Copying 0 resource
[INFO] Copying 7 resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ native-playground ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-resources-plugin:3.2.0:testResources (default-testResources) @ native-playground ---
[INFO] Not copying test resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ native-playground ---
[INFO] Not compiling test sources
[INFO] 
[INFO] --- maven-surefire-plugin:2.22.2:test (default-test) @ native-playground ---
[INFO] Tests are skipped.
[INFO] 
[INFO] --- native-maven-plugin:0.9.1:test (test-native) @ native-playground ---
[INFO] Tests are skipped.
[INFO] 
[INFO] --- maven-jar-plugin:3.2.0:jar (default-jar) @ native-playground ---
[INFO] Building jar: /home/kdvolder/tmp/graal/graal-bug-3671/target/native-playground-0.2.0-SNAPSHOT.jar
[INFO] 
[INFO] --- spring-boot-maven-plugin:2.5.4:repackage (repackage) @ native-playground ---
[INFO] Attaching repackaged archive /home/kdvolder/tmp/graal/graal-bug-3671/target/native-playground-0.2.0-SNAPSHOT-exec.jar with classifier exec
[INFO] 
[INFO] --- native-maven-plugin:0.9.1:build (build-native) @ native-playground ---
[INFO] ImageClasspath Entry: org.hibernate.validator:hibernate-validator:jar:6.1.7.Final:compile (file:///home/kdvolder/.m2/repository/org/hibernate/validator/hibernate-validator/6.1.7.Final/hibernate-validator-6.1.7.Final.jar)
[INFO] ImageClasspath Entry: jakarta.validation:jakarta.validation-api:jar:2.0.2:compile (file:///home/kdvolder/.m2/repository/jakarta/validation/jakarta.validation-api/2.0.2/jakarta.validation-api-2.0.2.jar)
[INFO] ImageClasspath Entry: org.jboss.logging:jboss-logging:jar:3.4.2.Final:compile (file:///home/kdvolder/.m2/repository/org/jboss/logging/jboss-logging/3.4.2.Final/jboss-logging-3.4.2.Final.jar)
[INFO] ImageClasspath Entry: com.fasterxml:classmate:jar:1.5.1:compile (file:///home/kdvolder/.m2/repository/com/fasterxml/classmate/1.5.1/classmate-1.5.1.jar)
[INFO] ImageClasspath Entry: com.vmware.tanzu.accelerator:native-playground:jar:0.2.0-SNAPSHOT (file:///home/kdvolder/tmp/graal/graal-bug-3671/target/native-playground-0.2.0-SNAPSHOT.jar)
[INFO] Executing: /home/kdvolder/Applications/graalvm-ce-java11-21.2.0/bin/native-image -cp /home/kdvolder/.m2/repository/org/hibernate/validator/hibernate-validator/6.1.7.Final/hibernate-validator-6.1.7.Final.jar:/home/kdvolder/.m2/repository/jakarta/validation/jakarta.validation-api/2.0.2/jakarta.validation-api-2.0.2.jar:/home/kdvolder/.m2/repository/org/jboss/logging/jboss-logging/3.4.2.Final/jboss-logging-3.4.2.Final.jar:/home/kdvolder/.m2/repository/com/fasterxml/classmate/1.5.1/classmate-1.5.1.jar:/home/kdvolder/tmp/graal/graal-bug-3671/target/native-playground-0.2.0-SNAPSHOT.jar --no-fallback --allow-incomplete-classpath --report-unsupported-elements-at-runtime -H:Class=com.acme.Exhibit -H:Name=native-playground
[native-playground:2658933]    classlist:   1,520.47 ms,  0.96 GB
[native-playground:2658933]        (cap):     488.39 ms,  0.96 GB
[native-playground:2658933]        setup:   2,085.86 ms,  0.96 GB
[native-playground:2658933]     (clinit):     307.07 ms,  2.36 GB
[native-playground:2658933]   (typeflow):   8,214.55 ms,  2.36 GB
[native-playground:2658933]    (objects):   5,739.65 ms,  2.36 GB
[native-playground:2658933]   (features):     623.08 ms,  2.36 GB
[native-playground:2658933]     analysis:  15,298.72 ms,  2.36 GB
[native-playground:2658933]     universe:   1,009.98 ms,  2.36 GB
[native-playground:2658933]      (parse):   2,049.03 ms,  2.79 GB
[native-playground:2658933]     (inline):   1,493.13 ms,  3.34 GB
[native-playground:2658933]    (compile):  13,208.32 ms,  3.75 GB
[native-playground:2658933]      compile:  17,835.92 ms,  3.75 GB
[native-playground:2658933]        image:   2,298.77 ms,  3.75 GB
[native-playground:2658933]        write:     302.34 ms,  3.75 GB
[native-playground:2658933]      [total]:  40,610.04 ms,  3.75 GB
# Printing build artifacts to: /home/kdvolder/tmp/graal/graal-bug-3671/target/native-playground.build_artifacts.txt
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  42.924 s
[INFO] Finished at: 2021-08-23T14:56:10-07:00
[INFO] ------------------------------------------------------------------------
Aug 23, 2021 2:56:10 PM org.hibernate.validator.internal.util.Version <clinit>
INFO: HV000001: Hibernate Validator 6.1.7.Final
Exception in thread "main" java.lang.ExceptionInInitializerError
	at com.oracle.svm.core.classinitialization.ClassInitializationInfo.initialize(ClassInitializationInfo.java:315)
	at org.hibernate.validator.internal.engine.valueextraction.ValueExtractorManager.<clinit>(ValueExtractorManager.java:60)
	at com.oracle.svm.core.classinitialization.ClassInitializationInfo.invokeClassInitializer(ClassInitializationInfo.java:375)
	at com.oracle.svm.core.classinitialization.ClassInitializationInfo.initialize(ClassInitializationInfo.java:295)
	at org.hibernate.validator.internal.engine.ValidatorFactoryImpl.<init>(ValidatorFactoryImpl.java:169)
	at org.hibernate.validator.HibernateValidator.buildValidatorFactory(HibernateValidator.java:38)
	at org.hibernate.validator.internal.engine.AbstractConfigurationImpl.buildValidatorFactory(AbstractConfigurationImpl.java:448)
	at com.acme.Exhibit.main(Exhibit.java:25)
Caused by: java.lang.NullPointerException
	at sun.reflect.annotation.TypeAnnotationParser.mapTypeAnnotations(TypeAnnotationParser.java:378)
	at sun.reflect.annotation.AnnotatedTypeFactory$AnnotatedTypeBaseImpl.<init>(AnnotatedTypeFactory.java:140)
	at sun.reflect.annotation.AnnotatedTypeFactory$AnnotatedArrayTypeImpl.<init>(AnnotatedTypeFactory.java:221)
	at sun.reflect.annotation.AnnotatedTypeFactory.buildAnnotatedType(AnnotatedTypeFactory.java:58)
	at sun.reflect.annotation.AnnotatedTypeFactory$AnnotatedParameterizedTypeImpl.getAnnotatedActualTypeArguments(AnnotatedTypeFactory.java:291)
	at org.hibernate.validator.internal.engine.valueextraction.ValueExtractorDescriptor.getContainerType(ValueExtractorDescriptor.java:116)
	at org.hibernate.validator.internal.engine.valueextraction.ValueExtractorDescriptor.<init>(ValueExtractorDescriptor.java:48)
	at org.hibernate.validator.internal.engine.valueextraction.ByteArrayValueExtractor.<clinit>(ByteArrayValueExtractor.java:16)
	at com.oracle.svm.core.classinitialization.ClassInitializationInfo.invokeClassInitializer(ClassInitializationInfo.java:375)
	at com.oracle.svm.core.classinitialization.ClassInitializationInfo.initialize(ClassInitializationInfo.java:295)
	... 7 more

@munishchouhan
Copy link
Contributor

@kdvolder As I see it is a spring boot app
can you please try spring native?
https://docs.spring.io/spring-native/docs/current/reference/htmlsingle/#overview

@kdvolder
Copy link

@mcraj017 It is not a spring boot app. That's probably not obvious because of the boot parent pom still being present. However, it just uses the spring boot parent pom as a convenience to allow building an executable jar and run it easier from commandline. However, there are no spring boot features being used in the code at all (i.e. zero boot annotations, and it is launching as plain Java app. Any spring and boot features in this sample have been deliberately disabled in an attempt to remove them as
irrellevant distractions. (Our real app from which this is derived is a however a Boot App and uses spring native and the error is the same though, so spring native doesn't help addressing this problem, if that is what you were wondering about).

@kdvolder
Copy link

kdvolder commented Aug 24, 2021

@mcraj017 To avoid confusion around how / if spring and spring boot are involved in this bug I've stripped down the sample a bit further and removed all spring boot references from the pom. It is now plain java project with but one dependency hibernate (+ transitive dependencies it needs). We are also no longer using spring boot fatjar to launch. The 'build-and-run-native' script has been updated accordingly. It now downloads maven dependencies into target/dependendies and uses an explicit -cp argument on the CLI to do the non-native run and collect reflection tracing info. Native image is then build using the collected configs + the manual config to include infos about sun.reflect.annotation.AnnotationType.

With all that in place the non-native run produces the following expected output:

Aug. 24, 2021 10:22:34 A.M. org.hibernate.validator.internal.util.Version <clinit>
INFO: HV000001: Hibernate Validator 6.1.7.Final
[ConstraintViolationImpl{interpolatedMessage='must not be blank', propertyPath=strings[1].<list element>, rootBeanClass=class com.acme.Exhibit, messageTemplate='{javax.validation.constraints.NotBlank.message}'}]

Running the native image results in this:

Aug 24, 2021 10:23:21 AM org.hibernate.validator.internal.util.Version <clinit>
INFO: HV000001: Hibernate Validator 6.1.7.Final
Exception in thread "main" java.lang.ExceptionInInitializerError
        at com.oracle.svm.core.classinitialization.ClassInitializationInfo.initialize(ClassInitializationInfo.java:315)
        at org.hibernate.validator.internal.engine.valueextraction.ValueExtractorManager.<clinit>(ValueExtractorManager.java:60)
        at com.oracle.svm.core.classinitialization.ClassInitializationInfo.invokeClassInitializer(ClassInitializationInfo.java:375)
        at com.oracle.svm.core.classinitialization.ClassInitializationInfo.initialize(ClassInitializationInfo.java:295)
        at org.hibernate.validator.internal.engine.ValidatorFactoryImpl.<init>(ValidatorFactoryImpl.java:169)
        at org.hibernate.validator.HibernateValidator.buildValidatorFactory(HibernateValidator.java:38)
        at org.hibernate.validator.internal.engine.AbstractConfigurationImpl.buildValidatorFactory(AbstractConfigurationImpl.java:448)
        at com.acme.Exhibit.main(Exhibit.java:25)
Caused by: java.lang.NullPointerException
        at sun.reflect.annotation.TypeAnnotationParser.mapTypeAnnotations(TypeAnnotationParser.java:378)
        at sun.reflect.annotation.AnnotatedTypeFactory$AnnotatedTypeBaseImpl.<init>(AnnotatedTypeFactory.java:140)
        at sun.reflect.annotation.AnnotatedTypeFactory$AnnotatedArrayTypeImpl.<init>(AnnotatedTypeFactory.java:221)
        at sun.reflect.annotation.AnnotatedTypeFactory.buildAnnotatedType(AnnotatedTypeFactory.java:58)
        at sun.reflect.annotation.AnnotatedTypeFactory$AnnotatedParameterizedTypeImpl.getAnnotatedActualTypeArguments(AnnotatedTypeFactory.java:291)
        at org.hibernate.validator.internal.engine.valueextraction.ValueExtractorDescriptor.getContainerType(ValueExtractorDescriptor.java:116)
        at org.hibernate.validator.internal.engine.valueextraction.ValueExtractorDescriptor.<init>(ValueExtractorDescriptor.java:48)
        at org.hibernate.validator.internal.engine.valueextraction.ByteArrayValueExtractor.<clinit>(ByteArrayValueExtractor.java:16)
        at com.oracle.svm.core.classinitialization.ClassInitializationInfo.invokeClassInitializer(ClassInitializationInfo.java:375)
        at com.oracle.svm.core.classinitialization.ClassInitializationInfo.initialize(ClassInitializationInfo.java:295)
        ... 7 more

Maven native image plugin is used with the following config:

<configuration>
   <mainClass>com.acme.Exhibit</mainClass>
   <buildArgs>--no-fallback --allow-incomplete-classpath
              --report-unsupported-elements-at-runtime</buildArgs>
</configuration>

This is the reworked sample in full: graal-bug-3671.zip

@munishchouhan
Copy link
Contributor

@kdvolder thanks for the clarification, I will check the reproducer and get back to you

@munishchouhan
Copy link
Contributor

@kdvolder I have raised the bug with Dev team

@julb
Copy link

julb commented Dec 2, 2021

Hello,
I confirm that I have the same issue on GraalVM 21.3
Is there a workaround available ?

@sdeleuze
Copy link
Collaborator

sdeleuze commented Dec 6, 2021

Any update ?

@radcortez
Copy link

I'm also experiencing the same issue. Any update on this? Thanks!

@sdeleuze
Copy link
Collaborator

Please tag this issue with the spring label.

@zakkak zakkak added the spring spring related issue label Mar 21, 2022
@radcortez
Copy link

Ping?

@loicottet
Copy link
Member

Closing as this issue has been fixed since 22.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug spring spring related issue
Projects
None yet
Development

No branches or pull requests

9 participants