1 /* 2 * Copyright (c) 2005, 2015, 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 5024104 27 * @summary Test ReferenceType.majorVersion(), minorVersion, constantPoolCount and ConstantPool apis. 28 * @author Swamy Venkataramanappa 29 * 30 * @run build TestScaffold VMConnection 31 * @run compile -g ConstantPoolInfo.java 32 * @run driver ConstantPoolInfo 33 */ 34 import com.sun.jdi.*; 35 import com.sun.jdi.event.*; 36 import com.sun.jdi.request.*; 37 38 import java.util.*; 39 import java.io.*; 40 41 /********** target program **********/ 42 43 class ConstantPoolTarg { 44 public static void main(String[] args){ 45 System.out.println("Howdy!"); // don't change the string value "Howdy!" it is 46 // used to test the constant pool entry 47 } 48 } 49 50 /********** test program **********/ 51 52 public class ConstantPoolInfo extends TestScaffold { 53 ReferenceType targetClass; 54 ThreadReference mainThread; 55 int cpool_count; 56 byte[] cpbytes; 57 static int expectedMajorVersion; 58 static int expectedMinorVersion; 59 static int expectedCpoolCount; 60 61 /* Class File Constants */ 62 public static final int JAVA_MAGIC = 0xcafebabe; 63 64 /* Constant table : copied from sun/javap */ 65 public static final int CONSTANT_UTF8 = 1; 66 public static final int CONSTANT_UNICODE = 2; 67 public static final int CONSTANT_INTEGER = 3; 68 public static final int CONSTANT_FLOAT = 4; 69 public static final int CONSTANT_LONG = 5; 70 public static final int CONSTANT_DOUBLE = 6; 71 public static final int CONSTANT_CLASS = 7; 72 public static final int CONSTANT_STRING = 8; 73 public static final int CONSTANT_FIELD = 9; 74 public static final int CONSTANT_METHOD = 10; 75 public static final int CONSTANT_INTERFACEMETHOD = 11; 76 public static final int CONSTANT_NAMEANDTYPE = 12; 77 78 ConstantPoolInfo (String args[]) { 79 super(args); 80 } 81 82 public static void main(String[] args) throws Exception { 83 new ConstantPoolInfo(args).startTests(); 84 } 85 86 /********** test core **********/ 87 88 protected void runTests() throws Exception { 89 /* 90 * Get to the top of main() 91 * to determine targetClass and mainThread 92 */ 93 BreakpointEvent bpe = startToMain("ConstantPoolTarg"); 94 targetClass = bpe.location().declaringType(); 95 mainThread = bpe.thread(); 96 97 98 String targPathname = System.getProperty("test.classes") + File.separator + "ConstantPoolTarg.class"; 99 100 readClassData(new FileInputStream(targPathname)); 101 102 /* Test constant pool apis 103 */ 104 if (vm().canGetClassFileVersion()) { 105 if (expectedMajorVersion != targetClass.majorVersion()) { 106 failure("unexpected major version: actual value: " + targetClass.majorVersion() 107 + "expected value :" + expectedMajorVersion); 108 109 } 110 if (expectedMinorVersion != targetClass.minorVersion()) { 111 failure("unexpected minor version: actual value: " + targetClass.minorVersion() 112 + "expected value :" + expectedMinorVersion); 113 114 } 115 } else { 116 System.out.println("can get class version not supported"); 117 } 118 119 120 if (vm().canGetConstantPool()) { 121 122 cpool_count = targetClass.constantPoolCount(); 123 124 cpbytes = targetClass.constantPool(); 125 126 try { 127 printcp(); 128 } catch (IOException x){ 129 System.out.println("IOexception reading cpool bytes " + x); 130 } 131 132 if (expectedCpoolCount != cpool_count) { 133 failure("unexpected constant pool count: actual value: " + cpool_count 134 + "expected value :" + expectedCpoolCount); 135 } 136 137 } else { 138 System.out.println("can get constant pool version not supported"); 139 } 140 141 142 /* 143 * resume until end 144 */ 145 listenUntilVMDisconnect(); 146 147 /* 148 * deal with results of test 149 * if anything has called failure("foo") testFailed will be true 150 */ 151 if (!testFailed) { 152 println("ConstantPoolInfo: passed"); 153 } else { 154 throw new Exception("ConstantPoolInfo: failed"); 155 } 156 } 157 158 public void printcp() throws IOException { 159 boolean found = false; 160 161 ByteArrayInputStream bytesStream = new ByteArrayInputStream(cpbytes); 162 DataInputStream in = new DataInputStream(bytesStream); 163 for (int i = 1; i < cpool_count; i++) { 164 int tag = in.readByte(); 165 System.out.print("const #" + i + ": "); 166 switch(tag) { 167 case CONSTANT_UTF8: 168 String str=in.readUTF(); 169 System.out.println("Asciz " + str); 170 // "Howdy!" is an expected constant pool entry 171 // of test program. It should exist. 172 if (str.compareTo("Howdy!") == 0) { 173 found = true; 174 } 175 break; 176 case CONSTANT_INTEGER: 177 System.out.println("int " + in.readInt()); 178 break; 179 case CONSTANT_FLOAT: 180 System.out.println("Float " + in.readFloat()); 181 break; 182 case CONSTANT_LONG: 183 System.out.println("Long " + in.readLong()); 184 break; 185 case CONSTANT_DOUBLE: 186 System.out.println("Double " + in.readDouble()); 187 break; 188 case CONSTANT_CLASS: 189 System.out.println("Class " + in.readUnsignedShort()); 190 break; 191 case CONSTANT_STRING: 192 System.out.println("String " + in.readUnsignedShort()); 193 break; 194 case CONSTANT_FIELD: 195 System.out.println("Field " + in.readUnsignedShort() + " " + in.readUnsignedShort()); 196 break; 197 case CONSTANT_METHOD: 198 System.out.println("Method " + in.readUnsignedShort() + " " + in.readUnsignedShort()); 199 break; 200 case CONSTANT_INTERFACEMETHOD: 201 System.out.println("InterfaceMethod " + in.readUnsignedShort() + " " + in.readUnsignedShort()); 202 break; 203 case CONSTANT_NAMEANDTYPE: 204 System.out.println("NameAndType " + in.readUnsignedShort() + " " + in.readUnsignedShort()); 205 break; 206 case 0: 207 default: 208 System.out.println("class format error"); 209 } 210 211 } 212 213 if (!found) { 214 failure("expected string \"Howdy!\" not found in constant pool"); 215 } 216 } 217 218 219 /** 220 * Read classfile 221 */ 222 void readClassData(InputStream infile){ 223 try{ 224 this.read(new DataInputStream(infile)); 225 }catch (FileNotFoundException ee) { 226 failure("cant read file"); 227 }catch (Error ee) { 228 ee.printStackTrace(); 229 failure("fatal error"); 230 } catch (Exception ee) { 231 ee.printStackTrace(); 232 failure("fatal exception"); 233 } 234 } 235 236 /** 237 * Read major, minor and cp count. 238 */ 239 public void read(DataInputStream in) throws IOException { 240 int magic = in.readInt(); 241 if (magic != JAVA_MAGIC) { 242 failure("fatal bad class file format"); 243 } 244 expectedMinorVersion = in.readShort();; 245 expectedMajorVersion = in.readShort(); 246 expectedCpoolCount = in.readUnsignedShort(); 247 in.close(); 248 } // end read() 249 }