comparison agent/src/share/classes/sun/jvm/hotspot/jdi/SAJDIClassLoader.java @ 0:a61af66fc99e jdk7-b24

Initial load
author duke
date Sat, 01 Dec 2007 00:00:00 +0000
parents
children c70a245cad3a
comparison
equal deleted inserted replaced
-1:000000000000 0:a61af66fc99e
1 /*
2 * Copyright 2003-2004 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 *
23 */
24
25 package sun.jvm.hotspot.jdi;
26
27 import java.io.*;
28 import java.net.*;
29
30 /*
31 * This class loader is used for two different reasons:
32 *
33 * 1) To support multiple simultaneous debuggees.
34 *
35 * SA's architecture does not allow us to use multiple simultaneous
36 * debuggees. This is because of lots of static fields caching
37 * vmStruct fields and singleton assumption in classes such as
38 * 'sun.jvm.hotspot.runtime.VM'. Hence, we use instances of this
39 * class loader to create a separate namespace for each debuggee VM.
40 *
41 * 2) To support cross VM version debugging.
42 *
43 * SA has very close dependency on VM data structures. Due to this, a
44 * version of SA can only support debuggees running a same dot-dot release and
45 * update releases only. For eg. this version of SA supports only 1.4.2 and
46 * 1.4.2_xx releases only. But, users may want to debug debuggees running
47 * a different version of VM. To support this, we use an instance of this
48 * class loader to load classes from corresponding sa-jdi.jar.
49 *
50 * Note that JDI classes would still be loaded from the debugger's tools.jar
51 * and not from debuggee's tools.jar. This means that if JDI interface evolved
52 * b/w debuggee and debugger VM versions, user may still get problems. This is
53 * the case when debugger runs on 1.5.0 and debuggee runs on 1.4.2. Because JDI
54 * evolved b/w these versions (generics, enum, varargs etc.), 1.4.2 sa-jdi.jar
55 * won't implement 1.5.0 JDI properly and user would get verifier errors. This
56 * class loader solution is suited for different dot-dot release where JDI will
57 * not evolve but VM data structures might change and SA implementation might
58 * have to change. For example, a debuggee running 1.5.1 VM can be debugged
59 * with debugger running on 1.5.0 VM. Here, JDI is same but VM data structures
60 * could still change.
61 */
62
63 class SAJDIClassLoader extends URLClassLoader {
64 private static final boolean DEBUG;
65 static {
66 DEBUG = System.getProperty("sun.jvm.hotspot.jdi.SAJDIClassLoader.DEBUG") != null;
67 }
68
69 private ClassLoader parent;
70 private boolean classPathSet;
71
72 SAJDIClassLoader(ClassLoader parent) {
73 super(new URL[0], parent);
74 this.parent = parent;
75 }
76
77 SAJDIClassLoader(ClassLoader parent, String classPath) {
78 this(parent);
79 this.classPathSet = true;
80 try {
81 addURL(new File(classPath).toURL());
82 } catch(MalformedURLException mue) {
83 throw new RuntimeException(mue);
84 }
85 }
86
87 public synchronized Class loadClass(String name)
88 throws ClassNotFoundException {
89 // First, check if the class has already been loaded
90 Class c = findLoadedClass(name);
91 if (c == null) {
92 /* If we are loading any class in 'sun.jvm.hotspot.' or any of the
93 * sub-packages (except for 'debugger' sub-pkg. please refer below),
94 * we load it by 'this' loader. Or else, we forward the request to
95 * 'parent' loader, system loader etc. (rest of the code follows
96 * the patten in java.lang.ClassLoader.loadClass).
97 *
98 * 'sun.jvm.hotspot.debugger.' and sub-package classes are
99 * also loaded by parent loader. This is done for two reasons:
100 *
101 * 1. to avoid code bloat by too many classes.
102 * 2. to avoid loading same native library multiple times
103 * from multiple class loaders (which results in getting a
104 * UnsatisifiedLinkageError from System.loadLibrary).
105 */
106
107 if (name.startsWith("sun.jvm.hotspot.") &&
108 !name.startsWith("sun.jvm.hotspot.debugger.")) {
109 return findClass(name);
110 }
111 if (parent != null) {
112 c = parent.loadClass(name);
113 } else {
114 c = findSystemClass(name);
115 }
116 }
117 return c;
118 }
119
120 protected Class findClass(String name) throws ClassNotFoundException {
121 if (DEBUG) {
122 System.out.println("SA/JDI loader: about to load " + name);
123 }
124 if (classPathSet) {
125 return super.findClass(name);
126 } else {
127 byte[] b = null;
128 try {
129 InputStream in = getResourceAsStream(name.replace('.', '/') + ".class");
130 // Read until end of stream is reached
131 b = new byte[1024];
132 int total = 0;
133 int len = 0;
134 while ((len = in.read(b, total, b.length - total)) != -1) {
135 total += len;
136 if (total >= b.length) {
137 byte[] tmp = new byte[total * 2];
138 System.arraycopy(b, 0, tmp, 0, total);
139 b = tmp;
140 }
141 }
142 // Trim array to correct size, if necessary
143 if (total != b.length) {
144 byte[] tmp = new byte[total];
145 System.arraycopy(b, 0, tmp, 0, total);
146 b = tmp;
147 }
148 } catch (Exception exp) {
149 throw (ClassNotFoundException) new ClassNotFoundException().initCause(exp);
150 }
151 return defineClass(name, b, 0, b.length);
152 }
153 }
154 }