1 /* 2 * Copyright (c) 2017, 2018, 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 import jdk.internal.org.objectweb.asm.*; 25 26 /* 27 * @test 28 * @summary Test scenarios for constant pool CONSTANT_Module and CONSTANT_Package 29 * types, for class file versions 53 and 52, when ACC_MODULE is set and 30 * not set in the access_flags. 31 * @bug 8175383 32 * @library /test/lib 33 * @modules java.base/jdk.internal.org.objectweb.asm 34 * @compile -XDignore.symbol.file ConstModule.java 35 * @run main ConstModule 36 */ 37 38 public class ConstModule { 39 40 static final int ACC_MODULE = 0x8000; 41 static final boolean MODULE_TEST = true; 42 static final boolean PACKAGE_TEST = false; 43 static final boolean CFE_EXCEPTION = true; 44 static final boolean NCDFE_EXCEPTION = false; 45 main(String[] args)46 public static void main(String[] args) throws Exception { 47 48 // Test that the JVM throws CFE for constant pool CONSTANT_Module type, for 49 // class file version 53, when ACC_MODULE is not set in the access_flags. 50 ConstModule.write_and_load(Opcodes.V9, 51 Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT + Opcodes.ACC_SYNTHETIC, 52 "jdk.fooMod", "FooMod", MODULE_TEST, CFE_EXCEPTION); 53 54 // Test that the JVM throws NCDFE for constant pool CONSTANT_Module type, 55 // for class file version 53, when ACC_MODULE is set in the access_flags. 56 ConstModule.write_and_load(Opcodes.V9, 57 Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT + Opcodes.ACC_SYNTHETIC + ACC_MODULE, 58 "jdk.fooModACC", "FooModACC", MODULE_TEST, NCDFE_EXCEPTION); 59 60 // Test that the JVM throws CFE for constant pool CONSTANT_Module type, for 61 // class file version 52, even when ACC_MODULE is set in the access_flags. 62 ConstModule.write_and_load(Opcodes.V1_8, 63 Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT + Opcodes.ACC_SYNTHETIC + ACC_MODULE, 64 "jdk.fooModACC52", "FooModACC52", MODULE_TEST, CFE_EXCEPTION); 65 66 // Test that the JVM throws CFE for constant pool CONSTANT_Package type, for 67 // class file version 53, when ACC_MODULE is not set in the access_flags. 68 ConstModule.write_and_load(Opcodes.V9, 69 Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT + Opcodes.ACC_SYNTHETIC, 70 "jdk.fooPkg", "FooPkg", PACKAGE_TEST, CFE_EXCEPTION); 71 72 // Test that the JVM throws NCDFE for constant pool CONSTANT_Package type, 73 // for class file version 53, when ACC_MODULE is set in the access_flags. 74 ConstModule.write_and_load(Opcodes.V9, 75 Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT + Opcodes.ACC_SYNTHETIC + ACC_MODULE, 76 "jdk.fooModACC", "FooModACC", PACKAGE_TEST, NCDFE_EXCEPTION); 77 78 // Test that the JVM throws CFE for constant pool CONSTANT_Package type, for 79 // class file version 52, even when ACC_MODULE is set in the access_flags. 80 ConstModule.write_and_load(Opcodes.V1_8, 81 Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT + Opcodes.ACC_SYNTHETIC + ACC_MODULE, 82 "jdk.fooModACC52", "FooModACC52", PACKAGE_TEST, CFE_EXCEPTION); 83 84 } 85 write_and_load(int version, int access_flags, String attr, String class_name, boolean module_test, boolean throwCFE)86 public static void write_and_load(int version, 87 int access_flags, 88 String attr, 89 String class_name, 90 boolean module_test, 91 boolean throwCFE) throws Exception { 92 ClassWriter cw = new ClassWriter(0); 93 cw.visit(version, 94 access_flags, 95 class_name, 96 null, 97 "java/lang/Object", 98 null); 99 100 if (module_test) 101 cw.visitAttribute(new TestModuleAttribute(attr)); 102 else 103 cw.visitAttribute(new TestPackageAttribute(attr)); 104 105 cw.visitEnd(); 106 byte[] bytes = cw.toByteArray(); 107 108 109 ClassLoader loader = new ClassLoader(ConstModule.class.getClassLoader()) { 110 @Override 111 protected Class<?> findClass(String cn)throws ClassNotFoundException { 112 if (cn.equals(class_name)) { 113 try { 114 Class superClass = super.defineClass(cn, bytes, 0, bytes.length); 115 throw new RuntimeException("Expected ClassFormatError not thrown"); 116 } catch (java.lang.ClassFormatError e) { 117 if (!throwCFE) { 118 throw new RuntimeException("Unexpected ClassFormatError exception: " + e.getMessage()); 119 } 120 if (module_test && !e.getMessage().contains( 121 "Unknown constant tag 19 in class file")) { 122 throw new RuntimeException("Wrong ClassFormatError exception: " + e.getMessage()); 123 } else if (!module_test && !e.getMessage().contains( 124 "Unknown constant tag 20 in class file")) { 125 throw new RuntimeException("Wrong ClassFormatError exception: " + e.getMessage()); 126 } 127 } catch (java.lang.NoClassDefFoundError f) { 128 if (throwCFE) { 129 throw new RuntimeException("Unexpected NoClassDefFoundError exception: " + f.getMessage()); 130 } 131 if (!f.getMessage().contains( 132 "is not a class because access_flag ACC_MODULE is set")) { 133 throw new RuntimeException("Wrong NoClassDefFoundError exception: " + f.getMessage()); 134 } 135 } 136 } else { 137 throw new ClassNotFoundException(cn); 138 } 139 return null; 140 } 141 }; 142 143 Class<?> clazz = loader.loadClass(class_name); 144 } 145 146 /** 147 * ConstModuleAttr attribute. 148 * 149 * <pre> {@code 150 * 151 * MainClass_attribute { 152 * // index to CONSTANT_utf8_info structure in constant pool representing 153 * // the string "ConstModuleAttr" 154 * u2 attribute_name_index; 155 * u4 attribute_length; 156 * 157 * // index to CONSTANT_Module_info structure 158 * u2 module_name_index 159 * } 160 * 161 * } </pre> 162 */ 163 public static class TestModuleAttribute extends Attribute { 164 private final String moduleName; 165 TestModuleAttribute(String moduleName)166 public TestModuleAttribute(String moduleName) { 167 super("ConstModuleAttr"); 168 this.moduleName = moduleName; 169 } 170 TestModuleAttribute()171 public TestModuleAttribute() { 172 this(null); 173 } 174 175 @Override read(ClassReader cr, int off, int len, char[] buf, int codeOff, Label[] labels)176 protected Attribute read(ClassReader cr, 177 int off, 178 int len, 179 char[] buf, 180 int codeOff, 181 Label[] labels) 182 { 183 String mn = cr.readModule(off, buf); 184 off += 2; 185 return new TestModuleAttribute(mn); 186 } 187 188 @Override write(ClassWriter cw, byte[] code, int len, int maxStack, int maxLocals)189 protected ByteVector write(ClassWriter cw, 190 byte[] code, 191 int len, 192 int maxStack, 193 int maxLocals) 194 { 195 ByteVector attr = new ByteVector(); 196 attr.putShort(cw.newModule(moduleName)); 197 return attr; 198 } 199 } 200 201 /** 202 * ConstPackageAttr attribute. 203 * 204 * <pre> {@code 205 * 206 * MainClass_attribute { 207 * // index to CONSTANT_utf8_info structure in constant pool representing 208 * // the string "ConstPackageAttr" 209 * u2 attribute_name_index; 210 * u4 attribute_length; 211 * 212 * // index to CONSTANT_Package_info structure 213 * u2 module_name_index 214 * } 215 * 216 * } </pre> 217 */ 218 public static class TestPackageAttribute extends Attribute { 219 private final String packageName; 220 TestPackageAttribute(String packageName)221 public TestPackageAttribute(String packageName) { 222 super("ConstPackageAttr"); 223 this.packageName = packageName; 224 } 225 TestPackageAttribute()226 public TestPackageAttribute() { 227 this(null); 228 } 229 230 @Override read(ClassReader cr, int off, int len, char[] buf, int codeOff, Label[] labels)231 protected Attribute read(ClassReader cr, 232 int off, 233 int len, 234 char[] buf, 235 int codeOff, 236 Label[] labels) 237 { 238 String mn = cr.readPackage(off, buf); 239 off += 2; 240 return new TestPackageAttribute(mn); 241 } 242 243 @Override write(ClassWriter cw, byte[] code, int len, int maxStack, int maxLocals)244 protected ByteVector write(ClassWriter cw, 245 byte[] code, 246 int len, 247 int maxStack, 248 int maxLocals) 249 { 250 ByteVector attr = new ByteVector(); 251 attr.putShort(cw.newPackage(packageName)); 252 return attr; 253 } 254 } 255 } 256