|  | /* | 
|  | * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. | 
|  | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 
|  | * | 
|  | * This code is free software; you can redistribute it and/or modify it | 
|  | * under the terms of the GNU General Public License version 2 only, as | 
|  | * published by the Free Software Foundation. | 
|  | * | 
|  | * This code is distributed in the hope that it will be useful, but WITHOUT | 
|  | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 
|  | * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License | 
|  | * version 2 for more details (a copy is included in the LICENSE file that | 
|  | * accompanied this code). | 
|  | * | 
|  | * You should have received a copy of the GNU General Public License version | 
|  | * 2 along with this work; if not, write to the Free Software Foundation, | 
|  | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | 
|  | * | 
|  | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | 
|  | * or visit www.oracle.com if you need additional information or have any | 
|  | * questions. | 
|  | */ | 
|  |  | 
|  | /** | 
|  | *  @test | 
|  | *  @bug 5024104 | 
|  | *  @summary Test ReferenceType.majorVersion(), minorVersion, constantPoolCount and ConstantPool apis. | 
|  | * | 
|  | *  @author Swamy Venkataramanappa | 
|  | * | 
|  | *  @run build TestScaffold VMConnection | 
|  | *  @run compile -g ConstantPoolInfo.java | 
|  | *  @run main ConstantPoolInfo | 
|  | */ | 
|  | import com.sun.jdi.*; | 
|  | import com.sun.jdi.event.*; | 
|  | import com.sun.jdi.request.*; | 
|  |  | 
|  | import java.util.*; | 
|  | import java.io.*; | 
|  |  | 
|  | /********** target program **********/ | 
|  |  | 
|  | class ConstantPoolTarg { | 
|  | public static void main(String[] args){ | 
|  | System.out.println("Howdy!"); // don't change the string value "Howdy!" it is | 
|  | // used to test the constant pool entry | 
|  | } | 
|  | } | 
|  |  | 
|  | /********** test program **********/ | 
|  |  | 
|  | public class ConstantPoolInfo extends TestScaffold { | 
|  | ReferenceType targetClass; | 
|  | ThreadReference mainThread; | 
|  | int cpool_count; | 
|  | byte[] cpbytes; | 
|  | static int expectedMajorVersion; | 
|  | static int expectedMinorVersion; | 
|  | static int expectedCpoolCount; | 
|  |  | 
|  | /* Class File Constants */ | 
|  | public static final int JAVA_MAGIC                   = 0xcafebabe; | 
|  |  | 
|  | /* Constant table :  copied from sun/javap */ | 
|  | public static final int CONSTANT_UTF8                = 1; | 
|  | public static final int CONSTANT_UNICODE             = 2; | 
|  | public static final int CONSTANT_INTEGER             = 3; | 
|  | public static final int CONSTANT_FLOAT               = 4; | 
|  | public static final int CONSTANT_LONG                = 5; | 
|  | public static final int CONSTANT_DOUBLE              = 6; | 
|  | public static final int CONSTANT_CLASS               = 7; | 
|  | public static final int CONSTANT_STRING              = 8; | 
|  | public static final int CONSTANT_FIELD               = 9; | 
|  | public static final int CONSTANT_METHOD              = 10; | 
|  | public static final int CONSTANT_INTERFACEMETHOD     = 11; | 
|  | public static final int CONSTANT_NAMEANDTYPE         = 12; | 
|  |  | 
|  | ConstantPoolInfo (String args[]) { | 
|  | super(args); | 
|  | } | 
|  |  | 
|  | public static void main(String[] args)      throws Exception { | 
|  | new ConstantPoolInfo(args).startTests(); | 
|  | } | 
|  |  | 
|  | /********** test core **********/ | 
|  |  | 
|  | protected void runTests() throws Exception { | 
|  | /* | 
|  | * Get to the top of main() | 
|  | * to determine targetClass and mainThread | 
|  | */ | 
|  | BreakpointEvent bpe = startToMain("ConstantPoolTarg"); | 
|  | targetClass = bpe.location().declaringType(); | 
|  | mainThread = bpe.thread(); | 
|  |  | 
|  |  | 
|  | String targPathname = System.getProperty("test.classes") + File.separator + "ConstantPoolTarg.class"; | 
|  |  | 
|  | readClassData(new FileInputStream(targPathname)); | 
|  |  | 
|  | /* Test constant pool apis | 
|  | */ | 
|  | if (vm().canGetClassFileVersion()) { | 
|  | if (expectedMajorVersion != targetClass.majorVersion()) { | 
|  | failure("unexpected major version: actual value: " + targetClass.majorVersion() | 
|  | + "expected value :" + expectedMajorVersion); | 
|  |  | 
|  | } | 
|  | if (expectedMinorVersion != targetClass.minorVersion()) { | 
|  | failure("unexpected minor version: actual value: " + targetClass.minorVersion() | 
|  | + "expected value :" + expectedMinorVersion); | 
|  |  | 
|  | } | 
|  | } else { | 
|  | System.out.println("can get class version not supported"); | 
|  | } | 
|  |  | 
|  |  | 
|  | if (vm().canGetConstantPool()) { | 
|  |  | 
|  | cpool_count = targetClass.constantPoolCount(); | 
|  |  | 
|  | cpbytes = targetClass.constantPool(); | 
|  |  | 
|  | try { | 
|  | printcp(); | 
|  | } catch (IOException x){ | 
|  | System.out.println("IOexception reading cpool bytes " + x); | 
|  | } | 
|  |  | 
|  | if (expectedCpoolCount != cpool_count) { | 
|  | failure("unexpected constant pool count: actual value: " + cpool_count | 
|  | + "expected value :" + expectedCpoolCount); | 
|  | } | 
|  |  | 
|  | } else { | 
|  | System.out.println("can get constant pool version not supported"); | 
|  | } | 
|  |  | 
|  |  | 
|  | /* | 
|  | * resume until end | 
|  | */ | 
|  | listenUntilVMDisconnect(); | 
|  |  | 
|  | /* | 
|  | * deal with results of test | 
|  | * if anything has called failure("foo") testFailed will be true | 
|  | */ | 
|  | if (!testFailed) { | 
|  | println("ConstantPoolInfo: passed"); | 
|  | } else { | 
|  | throw new Exception("ConstantPoolInfo: failed"); | 
|  | } | 
|  | } | 
|  |  | 
|  | public void printcp() throws IOException { | 
|  | boolean found = false; | 
|  |  | 
|  | ByteArrayInputStream bytesStream = new ByteArrayInputStream(cpbytes); | 
|  | DataInputStream in = new DataInputStream(bytesStream); | 
|  | for (int i = 1; i < cpool_count; i++) { | 
|  | int tag = in.readByte(); | 
|  | System.out.print("const #" + i + ":   "); | 
|  | switch(tag) { | 
|  | case CONSTANT_UTF8: | 
|  | String str=in.readUTF(); | 
|  | System.out.println("Asciz " + str); | 
|  | // "Howdy!" is an expected constant pool entry | 
|  | // of test program. It should exist. | 
|  | if (str.compareTo("Howdy!") == 0) { | 
|  | found = true; | 
|  | } | 
|  | break; | 
|  | case CONSTANT_INTEGER: | 
|  | System.out.println("int " + in.readInt()); | 
|  | break; | 
|  | case CONSTANT_FLOAT: | 
|  | System.out.println("Float " + in.readFloat()); | 
|  | break; | 
|  | case CONSTANT_LONG: | 
|  | System.out.println("Long " + in.readLong()); | 
|  | break; | 
|  | case CONSTANT_DOUBLE: | 
|  | System.out.println("Double " + in.readDouble()); | 
|  | break; | 
|  | case CONSTANT_CLASS: | 
|  | System.out.println("Class " + in.readUnsignedShort()); | 
|  | break; | 
|  | case CONSTANT_STRING: | 
|  | System.out.println("String " + in.readUnsignedShort()); | 
|  | break; | 
|  | case CONSTANT_FIELD: | 
|  | System.out.println("Field " + in.readUnsignedShort() + " " + in.readUnsignedShort()); | 
|  | break; | 
|  | case CONSTANT_METHOD: | 
|  | System.out.println("Method " + in.readUnsignedShort() + " " + in.readUnsignedShort()); | 
|  | break; | 
|  | case CONSTANT_INTERFACEMETHOD: | 
|  | System.out.println("InterfaceMethod " + in.readUnsignedShort() + " " + in.readUnsignedShort()); | 
|  | break; | 
|  | case CONSTANT_NAMEANDTYPE: | 
|  | System.out.println("NameAndType " + in.readUnsignedShort() + " " + in.readUnsignedShort()); | 
|  | break; | 
|  | case 0: | 
|  | default: | 
|  | System.out.println("class format error"); | 
|  | } | 
|  |  | 
|  | } | 
|  |  | 
|  | if (!found) { | 
|  | failure("expected string \"Howdy!\" not found in constant pool"); | 
|  | } | 
|  | } | 
|  |  | 
|  |  | 
|  | /** | 
|  | * Read classfile | 
|  | */ | 
|  | void readClassData(InputStream infile){ | 
|  | try{ | 
|  | this.read(new DataInputStream(infile)); | 
|  | }catch (FileNotFoundException ee) { | 
|  | failure("cant read file"); | 
|  | }catch (Error ee) { | 
|  | ee.printStackTrace(); | 
|  | failure("fatal error"); | 
|  | } catch (Exception ee) { | 
|  | ee.printStackTrace(); | 
|  | failure("fatal exception"); | 
|  | } | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Read major, minor and cp count. | 
|  | */ | 
|  | public void read(DataInputStream in) throws IOException { | 
|  | int magic = in.readInt(); | 
|  | if (magic != JAVA_MAGIC) { | 
|  | failure("fatal bad class file format"); | 
|  | } | 
|  | expectedMinorVersion = in.readShort();; | 
|  | expectedMajorVersion = in.readShort(); | 
|  | expectedCpoolCount = in.readUnsignedShort(); | 
|  | in.close(); | 
|  | } // end read() | 
|  | } |