quarkus: Java 17 records don't work in native image with GraalVM 21.3.0 JDK 17
Describe the bug
Java 17 records don’t work with GraalVM 21.3.0 when used as return types of resources that produce application/json. They also fail with SmallRye GraphQL.
In the reproducer I used quarkus-resteasy-jackson because Jackson supports records out of the box without any configuration.
When I create a native image like that with GraalVM 21.3 it works as expected.
public class App {
public static void main(String[] args) {
System.out.println(new F("x"));
}
static record F(String x) {
}
}
Expected behavior
Quarkus native should produce a binary.
Actual behavior
Native compilation fails with:
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.
Detailed message:
Trace:
at parsing java.lang.System$2.getConstantPool(System.java:2262)
Call path from entry point to java.lang.System$2.getConstantPool(Class):
at java.lang.System$2.getConstantPool(System.java:2262)
at java.lang.reflect.RecordComponent.declaredAnnotations(RecordComponent.java:198)
at java.lang.reflect.RecordComponent.getAnnotation(RecordComponent.java:181)
at io.smallrye.config.ConfigMappingInterface.getPropertyName(ConfigMappingInterface.java:691)
at io.smallrye.config.ConfigMappingInterface.getPropertyDef(ConfigMappingInterface.java:622)
at io.smallrye.config.ConfigMappingInterface.getProperties(ConfigMappingInterface.java:607)
at io.smallrye.config.ConfigMappingInterface.createConfigurationInterface(ConfigMappingInterface.java:564)
at io.smallrye.config.ConfigMappingInterface.access$000(ConfigMappingInterface.java:27)
at io.smallrye.config.ConfigMappingInterface$1.computeValue(ConfigMappingInterface.java:32)
at io.smallrye.config.ConfigMappingInterface$1.computeValue(ConfigMappingInterface.java:30)
at com.oracle.svm.core.jdk.Target_java_lang_ClassValue.get(JavaLangSubstitutions.java:596)
at io.quarkus.runtime.configuration.Substitutions$Target_ConfigMappingInterface.getConfigurationInterface(Substitutions.java:86)
at io.smallrye.config.ConfigMappingContext.lambda$getKeyConverter$6(ConfigMappingContext.java:142)
at io.smallrye.config.ConfigMappingContext$$Lambda$1290/0x00000007c1585240.apply(Unknown Source)
at sun.security.ec.ParametersMap$1.get(ParametersMap.java:78)
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:287)
at com.oracle.svm.jni.JNIJavaCallWrappers.jniInvoke_ARRAY_System_getProperty_deeeaa72a006d330408a3b7d002c7533e108bc28(generated:0)
How to Reproduce?
Given the following dependency:
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-jackson</artifactId>
</dependency>
This record:
public record Thing(String name) {
}
and the following resource
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
@Path("/hello")
public class ExampleResource {
@GET
@Produces(MediaType.APPLICATION_JSON)
public Thing hello() {
return new Thing("Hello RESTEasy");
}
}
A request like curl localhost:8080/hello returns
{"name":"Hello RESTEasy"}
The whole project is here: restrecords.zip
Reproduce with
./mvnw clean package -Pnative
on GraalVM 21.3 Java 17
An example using SmallRye GraphQL is available here: https://github.com/michael-simons/neo4j-aura-quarkus-graphql/tree/jdk17
Output of uname -a or ver
Darwin bs62.XXX 20.6.0 Darwin Kernel Version 20.6.0: Mon Aug 30 06:12:21 PDT 2021; root:xnu-7195.141.6~3/RELEASE_X86_64 x86_64
Output of java -version
openjdk version “17.0.1” 2021-10-19 OpenJDK Runtime Environment GraalVM CE 21.3.0 (build 17.0.1+12-jvmci-21.3-b05) OpenJDK 64-Bit Server VM GraalVM CE 21.3.0 (build 17.0.1+12-jvmci-21.3-b05, mixed mode, sharing)
GraalVM version (if different from Java)
21.3.0
Quarkus version or git rev
2.3.0
Build tool (ie. output of mvnw --version or gradlew --version)
Apache Maven 3.8.1 (05c21c65bdfed0f71a2f2ada8b84da59348c4c5d)
Additional information
No response
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 2
- Comments: 19 (15 by maintainers)
Upstream Graal VM will have this fixed in 21.3.2 and 22.1 releases (April 2022). Mandrel included this fix in
21.3.1.1-Finalearly, but will sync with upstream in April.Closing this as Quarkus
2.10will use GraalVM 22.1.Same issue here. Working adding
--report-unsupported-elements-at-runtimebut shouldn’t be the best option IMO…@zakkak this is still an issue with the released version of
21.3. Do you know anything about this?Upstream GraalVM issue: https://github.com/oracle/graal/issues/3984
I’ll have a look.
I added --report-unsupported-elements-at-runtime to quarkus.native.additional-build-args on the pom.xml and It worked. At github of graalvm have an issue where it’s recommended: https://github.com/oracle/graal/issues/3125.