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