1 7 8 package com.sun.jmx.mbeanserver; 9 10 import java.util.ArrayList ; 12 import java.util.Arrays ; 13 import java.util.Hashtable ; 14 import java.util.Iterator ; 15 import java.util.List ; 16 import java.util.Vector ; 17 18 import javax.management.ObjectName ; 20 import javax.management.loading.ClassLoaderRepository ; 21 import javax.management.loading.PrivateClassLoader ; 22 23 import com.sun.jmx.trace.Trace; 24 25 33 final class ClassLoaderRepositorySupport 34 implements ModifiableClassLoaderRepository { 35 36 42 private static class LoaderEntry { 43 ObjectName name; ClassLoader loader; 45 46 LoaderEntry(ObjectName name, ClassLoader loader) { 47 this.name = name; 48 this.loader = loader; 49 } 50 } 51 52 private static final LoaderEntry[] EMPTY_LOADER_ARRAY = new LoaderEntry[0]; 53 54 64 private LoaderEntry[] loaders = EMPTY_LOADER_ARRAY; 65 66 71 private synchronized boolean add(ObjectName name, ClassLoader cl) { 72 List l = new ArrayList (Arrays.asList(loaders)); 73 l.add(new LoaderEntry(name, cl)); 74 loaders = (LoaderEntry[]) l.toArray(EMPTY_LOADER_ARRAY); 75 return true; 76 } 77 78 90 private synchronized boolean remove(ObjectName name, ClassLoader cl) { 91 final int size = loaders.length; 92 for (int i = 0; i < size; i++) { 93 LoaderEntry entry = loaders[i]; 94 boolean match = 95 (name == null) ? 96 cl == entry.loader : 97 name.equals(entry.name); 98 if (match) { 99 LoaderEntry[] newloaders = new LoaderEntry[size - 1]; 100 System.arraycopy(loaders, 0, newloaders, 0, i); 101 System.arraycopy(loaders, i + 1, newloaders, i, 102 size - 1 - i); 103 loaders = newloaders; 104 return true; 105 } 106 } 107 return false; 108 } 109 110 111 114 private final Hashtable search= new Hashtable (10); 115 116 119 private final Hashtable loadersWithNames = new Hashtable (10); 120 121 122 private final static String dbgTag = "ClassLoaderRepositorySupport"; 123 124 125 public final Class loadClass(String className) 127 throws ClassNotFoundException { 128 return loadClass(loaders, className, null, null); 129 } 130 131 132 public final Class loadClassWithout(ClassLoader without, String className) 134 throws ClassNotFoundException { 135 if (isTraceOn()) { 136 trace("loadClassWithout", className + "\twithout " + without); 137 } 138 139 if (without == null) 142 return loadClass(loaders, className, null, null); 143 144 startValidSearch(without, className); 147 try { 148 return loadClass(loaders, className, without, null); 149 } finally { 150 stopValidSearch(without, className); 151 } 152 } 153 154 155 public final Class loadClassBefore(ClassLoader stop, String className) 156 throws ClassNotFoundException { 157 if (isTraceOn()) 158 trace("loadClassBefore", className + "\tbefore " + stop); 159 160 if (stop == null) 161 return loadClass(loaders, className, null, null); 162 163 startValidSearch(stop, className); 164 try { 165 return loadClass(loaders, className, null, stop); 166 } finally { 167 stopValidSearch(stop, className); 168 } 169 } 170 171 172 private Class loadClass(final LoaderEntry list[], 173 final String className, 174 final ClassLoader without, 175 final ClassLoader stop) 176 throws ClassNotFoundException { 177 final int size = list.length; 178 for(int i=0; i<size; i++) { 179 try { 180 final ClassLoader cl = list[i].loader; 181 if (cl == null) return Class.forName(className, false, null); 183 if (cl == without) 184 continue; 185 if (cl == stop) 186 break; 187 if (isTraceOn()) { 188 trace("loadClass", "trying loader = " + cl); 189 } 190 202 return Class.forName(className, false, cl); 203 } catch (ClassNotFoundException e) { 204 } 206 } 207 208 throw new ClassNotFoundException (className); 209 } 210 211 private synchronized void startValidSearch(ClassLoader aloader, 212 String className) 213 throws ClassNotFoundException { 214 Vector excluded= (Vector ) search.get(className); 217 if ((excluded!= null) && (excluded.contains(aloader))) { 218 if (isTraceOn()) { 219 trace("startValidSearch", "already requested loader=" + 220 aloader + " class= " + className); 221 } 222 throw new ClassNotFoundException (className); 223 } 224 225 if (excluded == null) { 228 excluded= new Vector (1); 229 search.put(className, excluded); 230 } 231 excluded.addElement(aloader); 232 if (isTraceOn()) { 233 trace("startValidSearch", "loader=" + aloader + " class= " + 234 className); 235 } 236 } 237 238 private synchronized void stopValidSearch(ClassLoader aloader, 239 String className) { 240 241 Vector excluded= (Vector ) search.get(className); 244 if (excluded!= null) { 245 excluded.removeElement(aloader); 246 if (isTraceOn()) { 247 trace("stopValidSearch", "loader=" + aloader + 248 " class= " + className); 249 } 250 } 251 } 252 253 public final void addClassLoader(ClassLoader loader) { 254 add(null, loader); 255 } 256 257 public final void removeClassLoader(ClassLoader loader) { 258 remove(null, loader); 259 } 260 261 public final synchronized void addClassLoader(ObjectName name, 262 ClassLoader loader) { 263 loadersWithNames.put(name, loader); 264 if (!(loader instanceof PrivateClassLoader )) 265 add(name, loader); 266 } 267 268 public final synchronized void removeClassLoader(ObjectName name) { 269 ClassLoader loader = (ClassLoader ) loadersWithNames.remove(name); 270 if (!(loader instanceof PrivateClassLoader )) 271 remove(name, loader); 272 } 273 274 public final ClassLoader getClassLoader(ObjectName name) { 275 return (ClassLoader )loadersWithNames.get(name); 276 } 277 278 281 private static boolean isTraceOn() { 282 return Trace.isSelected(Trace.LEVEL_TRACE, Trace.INFO_MBEANSERVER); 283 } 284 285 private static void trace(String clz, String func, String info) { 286 Trace.send(Trace.LEVEL_TRACE, Trace.INFO_MBEANSERVER,clz,func,info); 287 } 288 289 private static void trace(String func, String info) { 290 trace(dbgTag, func, info); 291 } 292 293 private static boolean isDebugOn() { 294 return Trace.isSelected(Trace.LEVEL_DEBUG, Trace.INFO_MBEANSERVER); 295 } 296 297 private static void debug(String clz, String func, String info) { 298 Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_MBEANSERVER,clz,func,info); 299 } 300 301 private static void debug(String func, String info) { 302 debug(dbgTag, func, info); 303 } 304 305 } 306 | Popular Tags |