/* */ package org.jboss.classloader.spi.base;
/* */
/* */ import java.io.IOException;
/* */ import java.io.InputStream;
/* */ import java.net.URL;
/* */ import java.security.AccessController;
/* */ import java.security.PrivilegedAction;
/* */ import java.security.PrivilegedActionException;
/* */ import java.security.PrivilegedExceptionAction;
/* */ import java.security.ProtectionDomain;
/* */ import java.security.SecureClassLoader;
/* */ import java.util.Enumeration;
/* */ import java.util.HashSet;
/* */ import java.util.Map;
/* */ import java.util.Set;
/* */ import java.util.concurrent.ConcurrentHashMap;
/* */ import java.util.concurrent.CopyOnWriteArraySet;
/* */ import java.util.concurrent.TimeUnit;
/* */ import java.util.concurrent.locks.ReentrantLock;
/* */ import javax.management.ObjectName;
/* */ import org.jboss.classloader.plugins.ClassLoaderUtils;
/* */ import org.jboss.classloader.spi.ClassLoaderPolicy;
/* */ import org.jboss.classloader.spi.DelegateLoader;
/* */ import org.jboss.classloader.spi.PackageInformation;
/* */ import org.jboss.classloading.spi.RealClassLoader;
/* */ import org.jboss.logging.Logger;
/* */ import org.jboss.util.collection.Iterators;
/* */
/* */ public class BaseClassLoader extends SecureClassLoader
/* */ implements BaseClassLoaderMBean, RealClassLoader
/* */ {
/* 61 */ private static final Logger log = Logger.getLogger(BaseClassLoader.class);
/* */
/* 64 */ private ReentrantLock lock = new ReentrantLock(true);
/* */ private ClassLoaderPolicy policy;
/* */ private DelegateLoader loader;
/* */ private Map<String, URL> resourceCache;
/* */ private Set<String> blackList;
/* */
/* */ public BaseClassLoader(ClassLoaderPolicy policy)
/* */ {
/* 87 */ super(null);
/* 88 */ if (policy == null)
/* 89 */ throw new IllegalArgumentException("Null policy");
/* 90 */ this.policy = policy;
/* */
/* 92 */ BaseClassLoaderPolicy basePolicy = policy;
/* 93 */ basePolicy.setClassLoader(this);
/* */
/* 95 */ this.loader = new DelegateLoader(policy);
/* */
/* 97 */ if (basePolicy.isCachable()) {
/* 98 */ this.resourceCache = new ConcurrentHashMap();
/* */ }
/* 100 */ if (basePolicy.isBlackListable()) {
/* 101 */ this.blackList = new CopyOnWriteArraySet();
/* */ }
/* 103 */ log.debug("Created " + this + " with policy " + policy.toLongString());
/* */ }
/* */
/* */ public ObjectName getObjectName()
/* */ {
/* 108 */ return this.policy.getObjectName();
/* */ }
/* */
/* */ ClassLoaderPolicy getPolicy()
/* */ {
/* 118 */ return this.policy;
/* */ }
/* */
/* */ DelegateLoader getLoader()
/* */ {
/* 128 */ return this.loader;
/* */ }
/* */
/* */ protected synchronized Class<?> loadClass(String name, boolean resolve)
/* */ throws ClassNotFoundException
/* */ {
/* 134 */ boolean trace = log.isTraceEnabled();
/* 135 */ if (trace) {
/* 136 */ log.trace(this + " loadClass " + name + " resolve=" + resolve);
/* */ }
/* */
/* 139 */ ClassLoaderUtils.checkClassName(name);
/* */
/* 142 */ Class result = findLoadedClass(name);
/* 143 */ if ((result != null) && (trace)) {
/* 144 */ log.trace(this + " already loaded class " + name + " " + ClassLoaderUtils.classToString(result));
/* */ }
/* */
/* 147 */ if (name.charAt(0) == '[')
/* */ {
/* 149 */ if (trace)
/* 150 */ log.trace(this + " resolving array class " + name + " using Class.forName()");
/* 151 */ result = Class.forName(name, true, this);
/* 152 */ if (trace) {
/* 153 */ log.trace(this + " resolved array " + ClassLoaderUtils.classToString(result));
/* */ }
/* */ }
/* */
/* 157 */ if (result == null) {
/* 158 */ result = loadClassFromDomain(name, trace);
/* */ }
/* */
/* 161 */ if (result == null)
/* */ {
/* 163 */ if (trace)
/* 164 */ log.trace(this + " class not found " + name);
/* 165 */ throw new ClassNotFoundException(name + " from " + toLongString());
/* */ }
/* */
/* 169 */ if (resolve)
/* */ {
/* 171 */ if (trace)
/* 172 */ log.trace(this + " resolveClass " + ClassLoaderUtils.classToString(result));
/* 173 */ resolveClass(result);
/* */ }
/* */
/* 176 */ return result;
/* */ }
/* */
/* */ public URL getResource(String name)
/* */ {
/* 182 */ BaseClassLoaderPolicy basePolicy = this.policy;
/* 183 */ BaseClassLoaderDomain domain = basePolicy.getClassLoaderDomain();
/* 184 */ boolean trace = log.isTraceEnabled();
/* 185 */ if (trace) {
/* 186 */ log.trace(this + " getResource " + name + " domain=" + domain);
/* */ }
/* 188 */ if (domain != null)
/* 189 */ return domain.getResource(this, name);
/* 190 */ return null;
/* */ }
/* */
/* */ protected Enumeration<URL> findResources(String name)
/* */ throws IOException
/* */ {
/* 197 */ BaseClassLoaderPolicy basePolicy = this.policy;
/* 198 */ BaseClassLoaderDomain domain = basePolicy.getClassLoaderDomain();
/* 199 */ boolean trace = log.isTraceEnabled();
/* 200 */ if (trace) {
/* 201 */ log.trace(this + " findResources " + name + " domain=" + domain);
/* */ }
/* 203 */ Set resourceURLs = new HashSet();
/* 204 */ if (domain != null)
/* 205 */ domain.getResources(this, name, resourceURLs);
/* 206 */ return Iterators.toEnumeration(resourceURLs.iterator());
/* */ }
/* */
/* */ Class<?> loadClassLocally(String name)
/* */ {
/* 217 */ return loadClassLocally(name, log.isTraceEnabled());
/* */ }
/* */
/* */ synchronized Class<?> loadClassLocally(String name, boolean trace)
/* */ {
/* 229 */ if (trace) {
/* 230 */ log.trace(this + " load class locally " + name);
/* */ }
/* */
/* 233 */ Class result = findLoadedClass(name);
/* 234 */ if (result != null)
/* */ {
/* 236 */ if (trace)
/* 237 */ log.trace(this + " already loaded " + ClassLoaderUtils.classToString(result));
/* 238 */ return result;
/* */ }
/* */
/* 242 */ String resourcePath = ClassLoaderUtils.classNameToPath(name);
/* */
/* 244 */ return (Class)AccessController.doPrivileged(new PrivilegedAction(resourcePath, trace, name)
/* */ {
/* */ public Class<?> run()
/* */ {
/* 248 */ InputStream is = BaseClassLoader.this.policy.getResourceAsStream(this.val$resourcePath);
/* 249 */ if (is == null)
/* */ {
/* 251 */ if (this.val$trace)
/* 252 */ BaseClassLoader.log.trace(this + " resource not found locally " + this.val$resourcePath + " for " + this.val$name);
/* 253 */ return null;
/* */ }
/* */
/* 257 */ byte[] byteCode = ClassLoaderUtils.loadByteCode(this.val$name, is);
/* */
/* 260 */ BaseClassLoaderPolicy basePolicy = BaseClassLoader.this.policy;
/* 261 */ ProtectionDomain protectionDomain = basePolicy.getProtectionDomain(this.val$name, this.val$resourcePath);
/* */ try
/* */ {
/* 264 */ byte[] transformed = BaseClassLoader.this.policy.transform(this.val$name, byteCode, protectionDomain);
/* 265 */ if (transformed != null)
/* 266 */ byteCode = transformed;
/* */ }
/* */ catch (Throwable t)
/* */ {
/* 270 */ throw new RuntimeException("Unexpected error transforming class " + this.val$name, t);
/* */ }
/* */
/* 274 */ BaseClassLoader.this.definePackage(this.val$name);
/* */ Class result;
/* */ Class result;
/* 278 */ if (protectionDomain != null)
/* 279 */ result = BaseClassLoader.this.defineClass(this.val$name, byteCode, 0, byteCode.length, protectionDomain);
/* */ else
/* 281 */ result = BaseClassLoader.this.defineClass(this.val$name, byteCode, 0, byteCode.length);
/* 282 */ if (this.val$trace)
/* 283 */ BaseClassLoader.log.trace(this + " loaded class locally " + ClassLoaderUtils.classToString(result));
/* 284 */ return result;
/* */ }
/* */ }
/* */ , this.policy.getAccessControlContext());
/* */ }
/* */
/* */ public URL getResourceLocally(String name)
/* */ {
/* 297 */ return getResourceLocally(name, log.isTraceEnabled());
/* */ }
/* */
/* */ URL getResourceLocally(String name, boolean trace)
/* */ {
/* 309 */ if (trace) {
/* 310 */ log.trace(this + " get resource locally " + name);
/* */ }
/* */
/* 313 */ if (this.resourceCache != null)
/* */ {
/* 315 */ URL url = (URL)this.resourceCache.get(name);
/* 316 */ if (url != null)
/* */ {
/* 318 */ if (trace)
/* 319 */ log.trace(this + " got resource from cache " + name);
/* 320 */ return url;
/* */ }
/* */
/* */ }
/* */
/* 325 */ if ((this.blackList != null) && (this.blackList.contains(name)))
/* */ {
/* 327 */ if (trace)
/* 328 */ log.trace(this + " resource is blacklisted " + name);
/* 329 */ return null;
/* */ }
/* */
/* 333 */ URL result = (URL)AccessController.doPrivileged(new PrivilegedAction(name, trace)
/* */ {
/* */ public URL run()
/* */ {
/* 338 */ URL result = BaseClassLoader.this.policy.getResource(this.val$name);
/* 339 */ if (result == null)
/* */ {
/* 341 */ if (this.val$trace)
/* 342 */ BaseClassLoader.log.trace(this + " resource not found locally " + this.val$name);
/* 343 */ return null;
/* */ }
/* 345 */ if (this.val$trace)
/* 346 */ BaseClassLoader.log.trace(this + " got resource locally " + this.val$name);
/* 347 */ return result;
/* */ }
/* */ }
/* */ , this.policy.getAccessControlContext());
/* */
/* 352 */ if ((this.resourceCache != null) && (result != null)) {
/* 353 */ this.resourceCache.put(name, result);
/* */ }
/* */
/* 356 */ if ((this.blackList != null) && (result == null)) {
/* 357 */ this.blackList.add(name);
/* */ }
/* 359 */ return result;
/* */ }
/* */
/* */ void getResourcesLocally(String name, Set<URL> urls)
/* */ throws IOException
/* */ {
/* 371 */ getResourcesLocally(name, urls, log.isTraceEnabled());
/* */ }
/* */
/* */ void getResourcesLocally(String name, Set<URL> urls, boolean trace)
/* */ throws IOException
/* */ {
/* 384 */ if (trace) {
/* 385 */ log.trace(this + " get resources locally " + name);
/* */ }
/* */
/* */ try
/* */ {
/* 390 */ AccessController.doPrivileged(new PrivilegedExceptionAction(name, urls)
/* */ {
/* */ public Object run() throws Exception
/* */ {
/* 394 */ BaseClassLoader.this.policy.getResources(this.val$name, this.val$urls);
/* 395 */ return null;
/* */ }
/* */ }
/* */ , this.policy.getAccessControlContext());
/* */ }
/* */ catch (PrivilegedActionException e)
/* */ {
/* 401 */ Exception e1 = e.getException();
/* 402 */ if ((e1 instanceof RuntimeException))
/* 403 */ throw ((RuntimeException)e1);
/* 404 */ if ((e1 instanceof IOException))
/* 405 */ throw ((IOException)e1);
/* 406 */ IOException e2 = new IOException("Unexpected error");
/* 407 */ e2.initCause(e1);
/* 408 */ throw e2;
/* */ }
/* */ }
/* */
/* */ protected void definePackage(String className)
/* */ {
/* 419 */ String packageName = ClassLoaderUtils.getClassPackageName(className);
/* 420 */ if (packageName.length() == 0) {
/* 421 */ return;
/* */ }
/* */
/* 424 */ Package pkge = getPackage(packageName);
/* 425 */ if (pkge != null) {
/* 426 */ return;
/* */ }
/* */
/* 429 */ PackageInformation pi = this.policy.getPackageInformation(packageName);
/* */ try
/* */ {
/* 432 */ if (pi != null)
/* 433 */ definePackage(packageName, pi.specTitle, pi.specVersion, pi.specVendor, pi.implTitle, pi.implVersion, pi.implVendor, pi.sealBase);
/* */ else
/* 435 */ definePackage(packageName, null, null, null, null, null, null, null);
/* */ }
/* */ catch (IllegalArgumentException alreadyDone)
/* */ {
/* */ }
/* */ }
/* */
/* */ protected Class<?> loadClassFromDomain(String name, boolean trace)
/* */ throws ClassNotFoundException
/* */ {
/* 459 */ acquireLockFairly(trace);
/* */ try
/* */ {
/* 463 */ BaseClassLoaderPolicy basePolicy = this.policy;
/* 464 */ BaseClassLoaderDomain domain = basePolicy.getClassLoaderDomain();
/* */
/* 466 */ if (trace) {
/* 467 */ log.trace(this + " load from domain " + name + " domain=" + domain);
/* */ }
/* */
/* 472 */ if (domain == null)
/* */ {
/* 474 */ Class result = loadClassLocally(name, trace);
/* */
/* 477 */ if (result == null)
/* 478 */ throw new IllegalStateException(this + " classLoader is not connected to a domain (probably undeployed?) for class " + name);
/* 479 */ localClass1 = result;
/* */ return localClass1;
/* */ }
/* 483 */ Class result = domain.loadClass(this, name);
/* 484 */ if ((result != null) && (trace))
/* 485 */ log.trace(this + " got class from domain " + ClassLoaderUtils.classToString(result));
/* 486 */ Class localClass1 = result;
/* */ return localClass1; } finally { unlock(trace); } throw localObject;
/* */ }
/* */
/* */ public boolean isValid()
/* */ {
/* 496 */ BaseClassLoaderPolicy basePolicy = this.policy;
/* 497 */ return basePolicy.getClassLoader() != null;
/* */ }
/* */
/* */ public Class<?> getCachedClass(String name)
/* */ {
/* 503 */ return null;
/* */ }
/* */
/* */ public URL getCachedResource(String name)
/* */ {
/* 509 */ return null;
/* */ }
/* */
/* */ public void clearBlackList(String name)
/* */ {
/* 514 */ if (this.blackList != null)
/* */ {
/* 516 */ boolean trace = log.isTraceEnabled();
/* 517 */ if (trace)
/* 518 */ log.trace(this + " removing from blacklist " + name);
/* 519 */ this.blackList.remove(name);
/* 520 */ this.policy.clearBlackList(name);
/* */ }
/* */ }
/* */
/* */ public String toLongString()
/* */ {
/* 531 */ StringBuilder builder = new StringBuilder();
/* 532 */ builder.append(getClass().getSimpleName());
/* 533 */ builder.append('@').append(Integer.toHexString(System.identityHashCode(this)));
/* 534 */ builder.append('{').append(getPolicy().toLongString());
/* 535 */ toLongString(builder);
/* 536 */ builder.append('}');
/* 537 */ return builder.toString();
/* */ }
/* */
/* */ protected void shutdownClassLoader()
/* */ {
/* 545 */ log.debug(toLongString() + " shutdown!");
/* 546 */ if (this.resourceCache != null)
/* 547 */ this.resourceCache.clear();
/* 548 */ if (this.blackList != null)
/* 549 */ this.blackList.clear();
/* */ }
/* */
/* */ protected void toLongString(StringBuilder builder)
/* */ {
/* */ }
/* */
/* */ public String toString()
/* */ {
/* 564 */ StringBuilder builder = new StringBuilder();
/* 565 */ builder.append(getClass().getSimpleName());
/* 566 */ builder.append('@').append(Integer.toHexString(System.identityHashCode(this)));
/* 567 */ return builder.toString();
/* */ }
/* */
/* */ boolean attemptLock()
/* */ {
/* 577 */ return attemptLock(log.isTraceEnabled());
/* */ }
/* */
/* */ void lock()
/* */ {
/* 587 */ acquireLockFairly(log.isTraceEnabled());
/* */ }
/* */
/* */ void unlock()
/* */ {
/* 595 */ unlock(log.isTraceEnabled());
/* */ }
/* */
/* */ private boolean attemptLock(boolean trace)
/* */ {
/* 606 */ Thread thread = Thread.currentThread();
/* 607 */ if (trace) {
/* 608 */ log.trace(this + " attemptLock " + thread);
/* */ }
/* 610 */ boolean interrupted = Thread.interrupted();
/* */
/* 612 */ boolean result = false;
/* */ try
/* */ {
/* 615 */ result = this.lock.tryLock(0L, TimeUnit.MICROSECONDS);
/* */ }
/* */ catch (InterruptedException ignored)
/* */ {
/* */ }
/* */ finally
/* */ {
/* 622 */ if (interrupted)
/* 623 */ thread.interrupt();
/* */ }
/* 625 */ if (trace)
/* */ {
/* 627 */ if (result)
/* 628 */ log.trace(this + " locked " + thread + " holding=" + this.lock.getHoldCount());
/* */ else {
/* 630 */ log.trace(this + " did NOT get the lock " + thread);
/* */ }
/* */ }
/* */
/* 634 */ if ((result) && (this.lock.getHoldCount() == 1)) {
/* 635 */ ClassLoaderManager.registerLoaderThread(this, thread);
/* */ }
/* 637 */ return result;
/* */ }
/* */
/* */ private void acquireLockFairly(boolean trace)
/* */ {
/* 649 */ Thread thread = Thread.currentThread();
/* 650 */ if (trace) {
/* 651 */ log.trace(this + " aquireLockFairly " + thread);
/* */ }
/* 653 */ boolean interrupted = Thread.interrupted();
/* */
/* 655 */ int waits = 0;
/* */ try
/* */ {
/* */ while (true)
/* */ {
/* 663 */ label44: if (!this.lock.tryLock(0L, TimeUnit.MICROSECONDS))
/* */ {
/* 666 */ if (waits++ == 12) {
/* 667 */ throw new IllegalStateException("Waiting too long to get the classloader lock: " + this);
/* */ }
/* 669 */ if (trace)
/* 670 */ log.trace(this + " waiting for lock " + thread);
/* 671 */ wait(10000L);
/* */ }
/* */ else
/* */ {
/* 675 */ if (trace)
/* 676 */ log.trace(this + " aquiredLock " + thread + " holding=" + this.lock.getHoldCount());
/* 677 */ break;
/* */ }
/* */ }
/* */ }
/* */ catch (InterruptedException ignored) {
/* 682 */ break label44;
/* */ }
/* */ finally
/* */ {
/* 687 */ if (interrupted) {
/* 688 */ thread.interrupt();
/* */ }
/* */ }
/* 691 */ if (this.lock.getHoldCount() == 1)
/* 692 */ ClassLoaderManager.registerLoaderThread(this, thread);
/* */ }
/* */
/* */ private void unlock(boolean trace)
/* */ {
/* 702 */ Thread thread = Thread.currentThread();
/* 703 */ if (trace) {
/* 704 */ log.trace(this + " unlock " + thread + " holding=" + this.lock.getHoldCount());
/* */ }
/* 706 */ this.lock.unlock();
/* */
/* 708 */ if (this.lock.getHoldCount() == 0) {
/* 709 */ ClassLoaderManager.unregisterLoaderThread(this, thread);
/* */ }
/* 711 */ synchronized (this)
/* */ {
/* 713 */ notifyAll();
/* */ }
/* */ }
/* */ }
/* Location: /home/mnovotny/projects/EMBEDDED_JBOSS_BETA3_COMMUNITY/embedded/output/lib/embedded-jboss/lib/jboss-embedded-all.jar
* Qualified Name: org.jboss.classloader.spi.base.BaseClassLoader
* JD-Core Version: 0.6.0
*/