diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 25035d790e7b5..d7b3f934724f6 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -110,6 +110,10 @@ jobs:
JDK: "labsjdk-ce-17"
GATE: "style,fullbuild"
PRIMARY: "espresso"
+ - env:
+ JDK: "labsjdk-ce-17"
+ GATE: "recordannotation"
+ PRIMARY: "substratevm"
steps:
- uses: actions/checkout@v2
with:
diff --git a/.gitignore b/.gitignore
index fb85d1054fb75..47681c8052db0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -52,4 +52,5 @@ bench-results.json
jmh_result.json
/vm/src/installer/dist/
/tools/generators/node_modules/
-/tools/generators/out/
\ No newline at end of file
+/tools/generators/out/
+target/
diff --git a/substratevm/mx.substratevm/mx_substratevm.py b/substratevm/mx.substratevm/mx_substratevm.py
index 81a0c7d403755..b1cb86523a61d 100644
--- a/substratevm/mx.substratevm/mx_substratevm.py
+++ b/substratevm/mx.substratevm/mx_substratevm.py
@@ -227,6 +227,7 @@ def __getattr__(self, name):
'muslcbuild',
'hellomodule',
'condconfig',
+ 'recordannotion',
])
def vm_native_image_path(config=None):
@@ -473,6 +474,10 @@ def help_stdout_check(output):
if t:
hellomodule([])
+ with Task('record annotation tests', tasks, tags=[GraalTags.recordannotation]) as t:
+ if t:
+ recordannotation([])
+
def native_unittests_task(extra_build_args=None):
if mx.is_windows():
@@ -1212,6 +1217,35 @@ def helloworld(args, config=None):
"""
run_helloworld_command(args, config, "helloworld")
+@mx.command(suite_name=suite.name, command_name='recordannotation-test')
+def recordannotation(args, config=None):
+ """
+ builds a native image of an annotated Record-using app.
+ """
+ jdk = get_jdk()
+ if jdk.javaCompliance >= '17':
+ # Build a record app module with maven
+ module_path = []
+ proj_dir = join(suite.dir, 'src', 'native-image-record-annot-tests')
+ mx.run_maven(['-e', 'package'], cwd=proj_dir)
+ module_path.append(join(proj_dir, 'target', 'recordannotations.jar'))
+ config = GraalVMConfig.build(native_images=['native-image', 'lib:native-image-agent', 'lib:native-image-diagnostics-agent'])
+ with native_image_context(hosted_assertions=False, config=config) as native_image:
+ module_path_sep = ';' if mx.is_windows() else ':'
+ run_args = [
+ '-ea',
+ '-p', module_path_sep.join(module_path), 'recordannotations.Main'
+ ]
+ # Build into native image
+ mx.log('Building image recordannotion: ' + str(module_path))
+ build_dir = join(svmbuild_dir(), 'recordannotations')
+ built_image = native_image([
+ '--verbose', '-H:Path=' + build_dir,
+ ] + run_args)
+ mx.log('Running image ' + built_image)
+ mx.run([built_image])
+ else:
+ mx.log('Record annotations test skipped as the JDK does not support it.')
@mx.command(suite_name=suite.name, command_name='hellomodule')
def hellomodule(args):
diff --git a/substratevm/src/native-image-record-annot-tests/pom.xml b/substratevm/src/native-image-record-annot-tests/pom.xml
new file mode 100644
index 0000000000000..8f005d8e35333
--- /dev/null
+++ b/substratevm/src/native-image-record-annot-tests/pom.xml
@@ -0,0 +1,53 @@
+
+
+ 4.0.0
+ records
+ recordannotations
+ 1
+
+ recordannotations
+
+
+ 3.2.0
+ 3.10.1
+ UTF-8
+ UTF-8
+
+
+
+
+ java-17
+
+ 17
+
+
+ recordannotations
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+
+ 17
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ ${maven-jar-plugin.version}
+
+
+
+ recordannotations.Main
+
+
+
+
+
+
+
+
+
+
diff --git a/substratevm/src/native-image-record-annot-tests/src/main/java/recordannotations/F.java b/substratevm/src/native-image-record-annot-tests/src/main/java/recordannotations/F.java
new file mode 100644
index 0000000000000..0e089dfd17a28
--- /dev/null
+++ b/substratevm/src/native-image-record-annot-tests/src/main/java/recordannotations/F.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package recordannotations;
+
+// Main record under test. See Main.
+@RCA2
+record F(@RCA @RCA2 String name, @RCA2 int i) {
+}
diff --git a/substratevm/src/native-image-record-annot-tests/src/main/java/recordannotations/Main.java b/substratevm/src/native-image-record-annot-tests/src/main/java/recordannotations/Main.java
new file mode 100644
index 0000000000000..90645909f37ec
--- /dev/null
+++ b/substratevm/src/native-image-record-annot-tests/src/main/java/recordannotations/Main.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package recordannotations;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.RecordComponent;
+import java.util.Arrays;
+import java.util.List;
+
+public class Main {
+
+ public static void main(String[] args) {
+ failIfAssertionsAreDisabled();
+
+ F x = new F("x", 1);
+
+ RecordComponent[] recordComponents = x.getClass().getRecordComponents();
+ assert recordComponents.length == 2;
+
+ // Verify String component annotations
+ RecordComponent stringComp = recordComponents[0];
+ List stringCompAnnot = Arrays.asList(stringComp.getAnnotations());
+ assert stringCompAnnot.size() == 2 : "expected 2 record annotations for string component";
+ assert stringCompAnnot.stream().anyMatch(a -> a.annotationType().getName().equals("recordannotations.RCA"));
+ assert stringCompAnnot.stream().anyMatch(a -> a.annotationType().getName().equals("recordannotations.RCA2"));
+ assert stringComp.getAnnotatedType().getType().getTypeName().equals(String.class.getTypeName());
+ Annotation rcaAnnotation = stringComp.getAnnotation(RCA.class);
+ assert rcaAnnotation != null : "expected RCA annotation to be present";
+ assert String.class.getTypeName().equals(stringComp.getGenericType().getTypeName());
+
+ // Verify int component annotations
+ RecordComponent intComp = recordComponents[1];
+ List intCompAnnot = Arrays.asList(intComp.getAnnotations());
+ assert intCompAnnot.size() == 1 : "expected 1 record annotations for int component";
+ assert intCompAnnot.stream().anyMatch(a -> a.annotationType().getName().equals("recordannotations.RCA2"));
+ assert intComp.getAnnotatedType().getType().getTypeName().equals(int.class.getTypeName());
+ assert intComp.getAnnotation(RCA.class) == null;
+ assert intComp.getAnnotation(RCA2.class) != null;
+ assert int.class.getTypeName().equals(intComp.getGenericType().getTypeName());
+
+ assert x.i() == 1;
+ assert "x".equals(x.name());
+
+ System.out.println("Record annotation tests passed!");
+ }
+
+ private static void failIfAssertionsAreDisabled() {
+ boolean enabled = false;
+ assert enabled = true;
+ if (!enabled) {
+ throw new AssertionError("This example requires that assertions are enabled (-ea)");
+ }
+ }
+
+}
diff --git a/substratevm/src/native-image-record-annot-tests/src/main/java/recordannotations/RCA.java b/substratevm/src/native-image-record-annot-tests/src/main/java/recordannotations/RCA.java
new file mode 100644
index 0000000000000..ea85ea37c7f7a
--- /dev/null
+++ b/substratevm/src/native-image-record-annot-tests/src/main/java/recordannotations/RCA.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package recordannotations;
+
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ ElementType.RECORD_COMPONENT, ElementType.FIELD })
+@interface RCA {
+ // empty
+}
+
diff --git a/substratevm/src/native-image-record-annot-tests/src/main/java/recordannotations/RCA2.java b/substratevm/src/native-image-record-annot-tests/src/main/java/recordannotations/RCA2.java
new file mode 100644
index 0000000000000..3fd5bef21bb02
--- /dev/null
+++ b/substratevm/src/native-image-record-annot-tests/src/main/java/recordannotations/RCA2.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package recordannotations;
+
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ ElementType.RECORD_COMPONENT, ElementType.FIELD, ElementType.TYPE })
+@interface RCA2 {
+ // empty
+}
diff --git a/substratevm/src/native-image-record-annot-tests/src/main/resources/META-INF/native-image/reflect-config.json b/substratevm/src/native-image-record-annot-tests/src/main/resources/META-INF/native-image/reflect-config.json
new file mode 100644
index 0000000000000..84cf575967e44
--- /dev/null
+++ b/substratevm/src/native-image-record-annot-tests/src/main/resources/META-INF/native-image/reflect-config.json
@@ -0,0 +1,11 @@
+[
+ {
+ "name" : "recordannotations.F",
+ "allDeclaredConstructors" : true,
+ "allPublicConstructors" : true,
+ "allDeclaredMethods" : true,
+ "allPublicMethods" : true,
+ "allDeclaredClasses" : true,
+ "allPublicClasses" : true
+ }
+]