1 /* 2 * Copyright (c) 2022, 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 8281323 27 * @summary Check emission of LoadableDescriptors attribute to make sure javac does not emit unneeded entries. 28 * @modules jdk.jdeps/com.sun.tools.classfile 29 * @enablePreview 30 * @run main NoUnnecessaryLoadableDescriptorsTest 31 */ 32 33 import com.sun.tools.classfile.*; 34 import com.sun.tools.classfile.ConstantPool.CONSTANT_Utf8_info; 35 36 public class NoUnnecessaryLoadableDescriptorsTest { 37 38 public value class LoadableDescriptorsTest1 { 39 byte b; 40 public LoadableDescriptorsTest1(byte b) { 41 this.b = b; 42 } 43 } 44 45 public class LoadableDescriptorsTest2 { 46 static class Inner1 { 47 static value class Inner2 {} 48 Inner2 inner; 49 } 50 } 51 52 public static void main(String[] args) throws Exception { 53 54 // There should be no LoadableDescriptors attribute in NoUnnecessaryLoadableDescriptorsTest.class 55 ClassFile cls = ClassFile.read(NoUnnecessaryLoadableDescriptorsTest.class.getResourceAsStream("NoUnnecessaryLoadableDescriptorsTest.class")); 56 57 if (cls == null) { 58 throw new AssertionError("Could not locate the class files"); 59 } 60 61 /* Check emission of LoadableDescriptors attribute */ 62 LoadableDescriptors_attribute LoadableDescriptors = (LoadableDescriptors_attribute) cls.attributes.get(Attribute.LoadableDescriptors); 63 if (LoadableDescriptors != null) { 64 throw new AssertionError("Unexpected LoadableDescriptors attribute!"); 65 } 66 67 // There should be no LoadableDescriptors attribute in NoUnnecessaryLoadableDescriptorsTest$LoadableDescriptorsTest1.class 68 cls = ClassFile.read(NoUnnecessaryLoadableDescriptorsTest.class.getResourceAsStream("NoUnnecessaryLoadableDescriptorsTest$LoadableDescriptorsTest1.class")); 69 70 if (cls == null) { 71 throw new AssertionError("Could not locate the class files"); 72 } 73 74 /* Check emission of LoadableDescriptors attribute */ 75 LoadableDescriptors = (LoadableDescriptors_attribute) cls.attributes.get(Attribute.LoadableDescriptors); 76 if (LoadableDescriptors != null) { 77 throw new AssertionError("Unexpected LoadableDescriptors attribute!"); 78 } 79 80 // There should be no LoadableDescriptors attribute in NoUnnecessaryLoadableDescriptorsTest$PreloadTest2.class 81 cls = ClassFile.read(NoUnnecessaryLoadableDescriptorsTest.class.getResourceAsStream("NoUnnecessaryLoadableDescriptorsTest$LoadableDescriptorsTest2.class")); 82 83 if (cls == null) { 84 throw new AssertionError("Could not locate the class files"); 85 } 86 87 /* Check emission of LoadableDescriptors attribute */ 88 LoadableDescriptors = (LoadableDescriptors_attribute) cls.attributes.get(Attribute.LoadableDescriptors); 89 if (LoadableDescriptors != null) { 90 throw new AssertionError("Unexpected LoadableDescriptors attribute!"); 91 } 92 93 // There should be no LoadableDescriptors attribute in NoUnnecessaryLoadableDescriptorsTest$LoadableDescriptorsTest2$Inner2.class 94 cls = ClassFile.read(NoUnnecessaryLoadableDescriptorsTest.class.getResourceAsStream("NoUnnecessaryLoadableDescriptorsTest$LoadableDescriptorsTest2$Inner1$Inner2.class")); 95 96 if (cls == null) { 97 throw new AssertionError("Could not locate the class files"); 98 } 99 100 /* Check emission of LoadableDescriptors attribute */ 101 LoadableDescriptors = (LoadableDescriptors_attribute) cls.attributes.get(Attribute.LoadableDescriptors); 102 if (LoadableDescriptors != null) { 103 throw new AssertionError("Unexpected LoadableDescriptors attribute!"); 104 } 105 106 // There should be ONE LoadableDescriptors attribute entry in NoUnnecessaryLoadableDescriptorsTest$LoadableDescriptorsTest2$Inner1.class 107 cls = ClassFile.read(NoUnnecessaryLoadableDescriptorsTest.class.getResourceAsStream("NoUnnecessaryLoadableDescriptorsTest$LoadableDescriptorsTest2$Inner1.class")); 108 109 if (cls == null) { 110 throw new AssertionError("Could not locate the class files"); 111 } 112 113 /* Check emission of LoadableDescriptors attribute */ 114 LoadableDescriptors = (LoadableDescriptors_attribute) cls.attributes.get(Attribute.LoadableDescriptors); 115 if (LoadableDescriptors == null) { 116 throw new AssertionError("Missing LoadableDescriptors attribute!"); 117 } 118 119 if (LoadableDescriptors.number_of_descriptors != 1) { 120 throw new AssertionError("Incorrect number of LoadableDescriptors classes"); 121 } 122 123 CONSTANT_Utf8_info utf8Info = cls.constant_pool.getUTF8Info(LoadableDescriptors.descriptors[0]); 124 System.err.println("utf8 " + utf8Info.value); 125 if (!utf8Info.value.equals("LNoUnnecessaryLoadableDescriptorsTest$LoadableDescriptorsTest2$Inner1$Inner2;")) { 126 throw new AssertionError("Expected LoadableDescriptors class entry is missing, but found " + utf8Info.value); 127 } 128 } 129 }