1 /* 2 * Copyright (c) 2007, 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 package nsk.jdi.ObjectReference.referringObjects.referringObjects002; 24 25 import nsk.share.ClassUnloader; 26 import nsk.share.ObjectInstancesManager; 27 import nsk.share.ReferringObject; 28 import nsk.share.TestBug; 29 import nsk.share.jdi.HeapwalkingDebuggee; 30 import java.io.*; 31 import java.util.*; 32 33 /* 34 * Class create and save given number of class instances 35 */ 36 class Instances { Instances(Class<?> klass, int instanceCount)37 Instances(Class<?> klass, int instanceCount) { 38 try { 39 for (int i = 0; i < instanceCount; i++) 40 instances.add(klass.newInstance()); 41 } catch (Throwable t) { 42 throw new TestBug("Unexpected error during test class instantiation: " + t); 43 } 44 } 45 46 private List<Object> instances = new ArrayList<Object>(); 47 } 48 49 /* 50 * Debuggee class handle request for loading classes with custom classloader and creating class instances 51 */ 52 public class referringObjects002a extends HeapwalkingDebuggee { 53 private Map<String, Instances> classesInstances = new HashMap<String, Instances>(); 54 55 private List<ReferringObject> classReferrers = new ArrayList<ReferringObject>(); 56 57 final static public String COMMAND_DELETE_CLASS_OBJECT_REFERRERS = "deleteClassObjectReferrers"; 58 main(String args[])59 public static void main(String args[]) { 60 new referringObjects002a().doTest(args); 61 } 62 63 // create references of all possible types to class object createClassObjectReferrers(String className, int instanceCount)64 public void createClassObjectReferrers(String className, int instanceCount) { 65 ClassUnloader unloader = loadedClasses.get(className); 66 67 if (unloader == null) 68 throw new TestBug("Unloader is null for class: " + className); 69 70 Class<?> klass = unloader.getLoadedClass(); 71 72 if (klass == null) 73 throw new TestBug("Unloader return null class object, for classname: " + className); 74 75 classesInstances.put(className, new Instances(klass, instanceCount)); 76 77 for (String referenceType : ObjectInstancesManager.allReferenceTypes) 78 classReferrers.add(new ReferringObject(klass, referenceType)); 79 } 80 81 // delete all created references to class object deleteClassObjectReferrers()82 public void deleteClassObjectReferrers() { 83 classesInstances = null; 84 85 for (ReferringObject referrer : classReferrers) 86 referrer.delete(); 87 88 classReferrers.clear(); 89 } 90 parseCommand(String command)91 public boolean parseCommand(String command) { 92 if (super.parseCommand(command)) { 93 // need do some additional actions for COMMAND_LOAD_CLASS 94 if (!command.startsWith(COMMAND_LOAD_CLASS)) 95 return true; 96 } 97 98 try { 99 StreamTokenizer tokenizer = new StreamTokenizer(new StringReader(command)); 100 tokenizer.whitespaceChars(':', ':'); 101 102 if (command.startsWith(COMMAND_LOAD_CLASS)) { 103 tokenizer.nextToken(); 104 105 if (tokenizer.nextToken() != StreamTokenizer.TT_WORD) 106 throw new IllegalArgumentException("Invalid command format"); 107 108 String className = tokenizer.sval; 109 110 if (tokenizer.nextToken() != StreamTokenizer.TT_NUMBER) 111 throw new IllegalArgumentException("Invalid command format"); 112 113 int instanceCount = (int) tokenizer.nval; 114 115 createClassObjectReferrers(className, instanceCount); 116 117 return true; 118 } else if (command.equals(COMMAND_DELETE_CLASS_OBJECT_REFERRERS)) { 119 deleteClassObjectReferrers(); 120 121 return true; 122 } 123 } catch (IOException e) { 124 throw new TestBug("Invalid command format: " + command); 125 } 126 127 return false; 128 } 129 130 } 131