1 /*
  2  * Copyright (c) 2024, 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  * @modules
 30  *      jdk.compiler/com.sun.tools.javac.code
 31  *      jdk.compiler/com.sun.tools.javac.util
 32  *      jdk.compiler/com.sun.tools.javac.api
 33  *      jdk.compiler/com.sun.tools.javac.file
 34  *      jdk.compiler/com.sun.tools.javac.main
 35  *      jdk.jdeps/com.sun.tools.classfile
 36  * @build toolbox.ToolBox toolbox.JavacTask
 37  * @run main LoadableDescriptorsAttrTest2
 38  */
 39 
 40 import java.nio.file.Path;
 41 import java.nio.file.Paths;
 42 
 43 import com.sun.tools.javac.code.Flags;
 44 import com.sun.tools.javac.util.Assert;
 45 import com.sun.tools.classfile.ClassFile;
 46 
 47 import toolbox.TestRunner;
 48 import toolbox.ToolBox;
 49 import toolbox.JavacTask;
 50 import toolbox.Task;
 51 
 52 public class LoadableDescriptorsAttrTest2 extends TestRunner {
 53     ToolBox tb = new ToolBox();
 54 
 55     public LoadableDescriptorsAttrTest2() {
 56         super(System.err);
 57     }
 58 
 59     protected void runTests() throws Exception {
 60         runTests(m -> new Object[] { Paths.get(m.getName()) });
 61     }
 62 
 63     Path[] findJavaFiles(Path... paths) throws Exception {
 64         return tb.findJavaFiles(paths);
 65     }
 66 
 67     public static void main(String... args) throws Exception {
 68         new LoadableDescriptorsAttrTest2().runTests();
 69     }
 70 
 71     @Test
 72     public void testLoadableDescField(Path base) throws Exception {
 73         Path src = base.resolve("src");
 74         tb.writeJavaFiles(src,
 75                 """
 76                 value class Val {}
 77                 """,
 78                 """
 79                 class Ident {
 80                     Val val;
 81                 }
 82                 """);
 83         Path classes = base.resolve("classes");
 84         tb.createDirectories(classes);
 85 
 86         new toolbox.JavacTask(tb)
 87                 .options("--enable-preview", "-source", Integer.toString(Runtime.version().feature()))
 88                 .outdir(classes)
 89                 .files(findJavaFiles(src))
 90                 .run()
 91                 .writeAll();
 92         Path classFilePath = classes.resolve("Ident.class");
 93         ClassFile classFile = ClassFile.read(classFilePath.toFile());
 94         Assert.check(classFile.minor_version == 65535);
 95         Assert.check(classFile.attributes.get("LoadableDescriptors") != null);
 96 
 97         // now with the value class in the classpath
 98         new toolbox.JavacTask(tb)
 99                 .options("--enable-preview", "-source", Integer.toString(Runtime.version().feature()), "-cp", classes.toString())
100                 .outdir(classes)
101                 .files(src.resolve("Ident.java"))
102                 .run()
103                 .writeAll();
104 
105         classFilePath = classes.resolve("Ident.class");
106         classFile = ClassFile.read(classFilePath.toFile());
107         Assert.check(classFile.minor_version == 65535);
108         Assert.check(classFile.attributes.get("LoadableDescriptors") != null);
109     }
110 
111     @Test
112     public void testLoadableDescMethodArg(Path base) throws Exception {
113         Path src = base.resolve("src");
114         tb.writeJavaFiles(src,
115                 """
116                 value class Val {}
117                 """,
118                 """
119                 class Ident {
120                     void m(Val val) {}
121                 }
122                 """);
123         Path classes = base.resolve("classes");
124         tb.createDirectories(classes);
125 
126         new toolbox.JavacTask(tb)
127                 .options("--enable-preview", "-source", Integer.toString(Runtime.version().feature()))
128                 .outdir(classes)
129                 .files(findJavaFiles(src))
130                 .run()
131                 .writeAll();
132         Path classFilePath = classes.resolve("Ident.class");
133         ClassFile classFile = ClassFile.read(classFilePath.toFile());
134         Assert.check(classFile.minor_version == 65535);
135         Assert.check(classFile.attributes.get("LoadableDescriptors") != null);
136 
137         // now with the value class in the classpath
138         new toolbox.JavacTask(tb)
139                 .options("--enable-preview", "-source", Integer.toString(Runtime.version().feature()), "-cp", classes.toString())
140                 .outdir(classes)
141                 .files(src.resolve("Ident.java"))
142                 .run()
143                 .writeAll();
144 
145         classFilePath = classes.resolve("Ident.class");
146         classFile = ClassFile.read(classFilePath.toFile());
147         Assert.check(classFile.minor_version == 65535);
148         Assert.check(classFile.attributes.get("LoadableDescriptors") != null);
149     }
150 
151     @Test
152     public void testLoadableDescReturnType(Path base) throws Exception {
153         Path src = base.resolve("src");
154         tb.writeJavaFiles(src,
155                 """
156                 value class Val {}
157                 """,
158                 """
159                 class Ident {
160                     Val m() {
161                         return null;
162                     }
163                 }
164                 """);
165         Path classes = base.resolve("classes");
166         tb.createDirectories(classes);
167 
168         new toolbox.JavacTask(tb)
169                 .options("--enable-preview", "-source", Integer.toString(Runtime.version().feature()))
170                 .outdir(classes)
171                 .files(findJavaFiles(src))
172                 .run()
173                 .writeAll();
174         Path classFilePath = classes.resolve("Ident.class");
175         ClassFile classFile = ClassFile.read(classFilePath.toFile());
176         Assert.check(classFile.minor_version == 65535);
177         Assert.check(classFile.attributes.get("LoadableDescriptors") != null);
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.read(classFilePath.toFile());
189         Assert.check(classFile.minor_version == 65535);
190         Assert.check(classFile.attributes.get("LoadableDescriptors") != null);
191     }
192 }