1 /*
2 * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 /*
25 * @test
26 * @bug 8331461
27 * @summary [lworld] javac is generating a class file with the LoadableDescriptors attribute but with minor version '0'
28 * @library /tools/lib
29 * @enablePreview
30 * @modules
31 * jdk.compiler/com.sun.tools.javac.code
32 * jdk.compiler/com.sun.tools.javac.util
33 * jdk.compiler/com.sun.tools.javac.api
34 * jdk.compiler/com.sun.tools.javac.file
35 * jdk.compiler/com.sun.tools.javac.main
36 * @build toolbox.ToolBox toolbox.JavacTask
37 * @run main LoadableDescriptorsAttrTest2
38 */
39
40 import java.lang.classfile.Attributes;
41 import java.lang.classfile.ClassFile;
42 import java.nio.file.Path;
43 import java.nio.file.Paths;
44
45 import com.sun.tools.javac.util.Assert;
46
47 import toolbox.TestRunner;
48 import toolbox.ToolBox;
49
50 public class LoadableDescriptorsAttrTest2 extends TestRunner {
51 ToolBox tb = new ToolBox();
52
53 public LoadableDescriptorsAttrTest2() {
54 super(System.err);
55 }
56
57 protected void runTests() throws Exception {
58 runTests(m -> new Object[] { Paths.get(m.getName()) });
59 }
60
61 Path[] findJavaFiles(Path... paths) throws Exception {
62 return tb.findJavaFiles(paths);
63 }
64
65 public static void main(String... args) throws Exception {
66 new LoadableDescriptorsAttrTest2().runTests();
67 }
68
69 @Test
70 public void testLoadableDescField(Path base) throws Exception {
71 Path src = base.resolve("src");
72 tb.writeJavaFiles(src,
73 """
74 value class Val {}
75 """,
76 """
77 class Ident {
78 Val val;
79 }
80 """);
81 Path classes = base.resolve("classes");
82 tb.createDirectories(classes);
83
84 new toolbox.JavacTask(tb)
85 .options("--enable-preview", "-source", Integer.toString(Runtime.version().feature()))
86 .outdir(classes)
87 .files(findJavaFiles(src))
88 .run()
89 .writeAll();
90 Path classFilePath = classes.resolve("Ident.class");
91 var classFile = ClassFile.of().parse(classFilePath);
92 Assert.check(classFile.minorVersion() == 65535);
93 Assert.check(classFile.findAttribute(Attributes.loadableDescriptors()).isPresent());
94
95 // now with the value class in the classpath
96 new toolbox.JavacTask(tb)
97 .options("--enable-preview", "-source", Integer.toString(Runtime.version().feature()), "-cp", classes.toString())
98 .outdir(classes)
99 .files(src.resolve("Ident.java"))
100 .run()
101 .writeAll();
102
103 classFilePath = classes.resolve("Ident.class");
104 classFile = ClassFile.of().parse(classFilePath);
105 Assert.check(classFile.minorVersion() == 65535);
106 Assert.check(classFile.findAttribute(Attributes.loadableDescriptors()).isPresent());
107 }
108
109 @Test
110 public void testLoadableDescMethodArg(Path base) throws Exception {
111 Path src = base.resolve("src");
112 tb.writeJavaFiles(src,
113 """
114 value class Val {}
115 """,
116 """
117 class Ident {
118 void m(Val val) {}
119 }
120 """);
121 Path classes = base.resolve("classes");
122 tb.createDirectories(classes);
123
124 new toolbox.JavacTask(tb)
125 .options("--enable-preview", "-source", Integer.toString(Runtime.version().feature()))
126 .outdir(classes)
127 .files(findJavaFiles(src))
128 .run()
129 .writeAll();
130 Path classFilePath = classes.resolve("Ident.class");
131 var classFile = ClassFile.of().parse(classFilePath);
132 Assert.check(classFile.minorVersion() == 65535);
133 Assert.check(classFile.findAttribute(Attributes.loadableDescriptors()).isPresent());
134
135 // now with the value class in the classpath
136 new toolbox.JavacTask(tb)
137 .options("--enable-preview", "-source", Integer.toString(Runtime.version().feature()), "-cp", classes.toString())
138 .outdir(classes)
139 .files(src.resolve("Ident.java"))
140 .run()
141 .writeAll();
142
143 classFilePath = classes.resolve("Ident.class");
144 classFile = ClassFile.of().parse(classFilePath);
145 Assert.check(classFile.minorVersion() == 65535);
146 Assert.check(classFile.findAttribute(Attributes.loadableDescriptors()).isPresent());
147
148 }
149
150 @Test
151 public void testLoadableDescReturnType(Path base) throws Exception {
152 Path src = base.resolve("src");
153 tb.writeJavaFiles(src,
154 """
155 value class Val {}
156 """,
157 """
158 class Ident {
159 Val m() {
160 return null;
161 }
162 }
163 """);
164 Path classes = base.resolve("classes");
165 tb.createDirectories(classes);
166
167 new toolbox.JavacTask(tb)
168 .options("--enable-preview", "-source", Integer.toString(Runtime.version().feature()))
169 .outdir(classes)
170 .files(findJavaFiles(src))
171 .run()
172 .writeAll();
173 Path classFilePath = classes.resolve("Ident.class");
174 var classFile = ClassFile.of().parse(classFilePath);
175 Assert.check(classFile.minorVersion() == 65535);
176 Assert.check(classFile.findAttribute(Attributes.loadableDescriptors()).isPresent());
177
178
179 // now with the value class in the classpath
180 new toolbox.JavacTask(tb)
181 .options("--enable-preview", "-source", Integer.toString(Runtime.version().feature()), "-cp", classes.toString())
182 .outdir(classes)
183 .files(src.resolve("Ident.java"))
184 .run()
185 .writeAll();
186
187 classFilePath = classes.resolve("Ident.class");
188 classFile = ClassFile.of().parse(classFilePath);
189 Assert.check(classFile.minorVersion() == 65535);
190 Assert.check(classFile.findAttribute(Attributes.loadableDescriptors()).isPresent());
191
192 }
193 }