graalvm / native-build-tools

Native-image plugins for various build tools
https://graalvm.github.io/native-build-tools/
Other
371 stars 61 forks source link

Running native-tests should include provided scope dependencies #562

Open stevenschlansker opened 10 months ago

stevenschlansker commented 10 months ago

When building native-tests using the agent, annotations from provided scope dependencies seem to not be available on the classpath, or at least are missing from annotation metadata.

Per Maven (https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html), the provided scope "is added to the classpath used for compilation and test, but not the runtime classpath"

To reproduce this, I created a simple Maven project that brings in jakarta.annotation-api in provided scope. With reflection, I query a constructor parameter's annotations. During surefire, this works OK, since provided scope is included in tests. When native-test runs, the annotation is missing, as if the provided scope dependency is not present.

https://github.com/stevenschlansker/graal-constructor-annotation/tree/main

In the project, mvn clean package results in:

...
[INFO] --- surefire:3.1.2:test (default-test) @ graal-constructor-annotation ---
[INFO] Using auto detected provider org.apache.maven.surefire.junitplatform.JUnitPlatformProvider
[INFO] 
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running org.sugis.graal.ConstructorAnnotationTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.044 s -- in org.sugis.graal.ConstructorAnnotationTest
...
[2/8] Performing analysis...  [****]                                                                     (5.4s @ 0.74GB)
    7,851 reachable types   (81.4% of    9,642 total)
   10,580 reachable fields  (58.9% of   17,972 total)
   37,218 reachable methods (53.9% of   69,043 total)
    2,519 types,   242 fields, and 1,385 methods registered for reflection
       59 types,    66 fields, and    55 methods registered for JNI access
        4 native libraries: -framework Foundation, dl, pthread, z
[3/8] Building universe...                                                                               (1.3s @ 0.61GB)
[4/8] Parsing methods...      [*]                                                                        (0.8s @ 0.74GB)
[5/8] Inlining methods...     [***]                                                                      (0.3s @ 0.95GB)
[6/8] Compiling methods...    [***]                                                                      (8.8s @ 0.86GB)
[7/8] Layouting methods...    [*]                                                                        (1.9s @ 0.75GB)
[8/8] Creating image...       [**]                                                                       (2.0s @ 1.21GB)
  16.90MB (51.69%) for code area:    20,619 compilation units
  15.25MB (46.64%) for image heap:  204,988 objects and 121 resources
 560.20kB ( 1.67%) for other data

Produced artifacts:
 /Users/steven/code/graal-constructor-annotation/target/native-tests (executable)
========================================================================================================================
Finished generating 'native-tests' in 23.4s.
[INFO] Executing: /Users/steven/code/graal-constructor-annotation/target/native-tests --xml-output-dir /Users/steven/code/graal-constructor-annotation/target/native-test-reports -Djunit.platform.listeners.uid.tracking.output.dir=/Users/steven/code/graal-constructor-annotation/target/test-ids
JUnit Platform on Native Image - report
----------------------------------------

org.sugis.graal.ConstructorAnnotationTest > testAnnotationPresent() FAILED

Failures (1):
  JUnit Jupiter:ConstructorAnnotationTest:testAnnotationPresent()
    MethodSource [className = 'org.sugis.graal.ConstructorAnnotationTest', methodName = 'testAnnotationPresent', methodParameterTypes = '']
    => java.lang.AssertionError: 
Expected size: 1 but was: 0 in:
[]
       org.sugis.graal.ConstructorAnnotationTest.testAnnotationPresent(ConstructorAnnotationTest.java:27)
       java.base@21.0.2/java.lang.reflect.Method.invoke(Method.java:580)
       java.base@21.0.2/java.util.ArrayList.forEach(ArrayList.java:1596)
       java.base@21.0.2/java.util.ArrayList.forEach(ArrayList.java:1596)

If you edit the pom.xml to remove the <scope>provided</scope> from the jakarta.annotation-api dependency, then the problem goes away and native-tests run OK.

Expected behavior: native-tests should behave like surefire and jakarta.annotation.Nullable should be available

System Info (please complete the following information):