169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/* 269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Javassist, a Java-bytecode translator toolkit. 369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Copyright (C) 1999-2007 Shigeru Chiba. All Rights Reserved. 469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * The contents of this file are subject to the Mozilla Public License Version 669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 1.1 (the "License"); you may not use this file except in compliance with 769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the License. Alternatively, the contents of this file may be used under 869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the terms of the GNU Lesser General Public License Version 2.1 or later. 969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 1069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Software distributed under the License is distributed on an "AS IS" basis, 1169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 1269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * for the specific language governing rights and limitations under the 1369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * License. 1469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 1569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 1669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpackage javassist.scopedpool; 1769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 1869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.util.ArrayList; 1969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.util.Collections; 2069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.util.Iterator; 2169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.util.Map; 2269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.util.WeakHashMap; 2369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 2469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.ClassPool; 2569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.LoaderClassPath; 2669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 2769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/** 2869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * An implementation of <code>ScopedClassPoolRepository</code>. 2969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * It is an singleton. 3069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 3169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @author <a href="kabir.khan@jboss.com">Kabir Khan</a> 3269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @version $Revision: 1.4 $ 3369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 3469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpublic class ScopedClassPoolRepositoryImpl implements ScopedClassPoolRepository { 3569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** The instance */ 3669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private static final ScopedClassPoolRepositoryImpl instance = new ScopedClassPoolRepositoryImpl(); 3769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 3869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** Whether to prune */ 3969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private boolean prune = true; 4069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 4169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** Whether to prune when added to the classpool's cache */ 4269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal boolean pruneWhenCached; 4369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 4469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** The registered classloaders */ 4569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected Map registeredCLs = Collections 4669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal .synchronizedMap(new WeakHashMap()); 4769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 4869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** The default class pool */ 4969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected ClassPool classpool; 5069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 5169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** The factory for creating class pools */ 5269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected ScopedClassPoolFactory factory = new ScopedClassPoolFactoryImpl(); 5369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 5469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 5569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Get the instance. 5669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 5769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return the instance. 5869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 5969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static ScopedClassPoolRepository getInstance() { 6069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return instance; 6169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 6269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 6369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 6469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Singleton. 6569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 6669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private ScopedClassPoolRepositoryImpl() { 6769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal classpool = ClassPool.getDefault(); 6869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // FIXME This doesn't look correct 6969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ClassLoader cl = Thread.currentThread().getContextClassLoader(); 7069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal classpool.insertClassPath(new LoaderClassPath(cl)); 7169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 7269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 7369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 7469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the value of the prune attribute. 7569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 7669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return the prune. 7769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 7869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public boolean isPrune() { 7969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return prune; 8069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 8169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 8269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 8369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Set the prune attribute. 8469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 8569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param prune a new value. 8669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 8769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void setPrune(boolean prune) { 8869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal this.prune = prune; 8969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 9069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 9169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 9269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Create a scoped classpool. 9369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 9469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param cl the classloader. 9569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param src the original classpool. 9669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return the classpool 9769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 9869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public ScopedClassPool createScopedClassPool(ClassLoader cl, ClassPool src) { 9969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return factory.create(cl, src, this); 10069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 10169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 10269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public ClassPool findClassPool(ClassLoader cl) { 10369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (cl == null) 10469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return registerClassLoader(ClassLoader.getSystemClassLoader()); 10569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 10669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return registerClassLoader(cl); 10769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 10869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 10969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 11069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Register a classloader. 11169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 11269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param ucl the classloader. 11369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return the classpool 11469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 11569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public ClassPool registerClassLoader(ClassLoader ucl) { 11669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal synchronized (registeredCLs) { 11769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // FIXME: Probably want to take this method out later 11869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // so that AOP framework can be independent of JMX 11969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // This is in here so that we can remove a UCL from the ClassPool as 12069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // a 12169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // ClassPool.classpath 12269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (registeredCLs.containsKey(ucl)) { 12369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return (ClassPool)registeredCLs.get(ucl); 12469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 12569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ScopedClassPool pool = createScopedClassPool(ucl, classpool); 12669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal registeredCLs.put(ucl, pool); 12769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return pool; 12869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 12969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 13069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 13169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 13269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Get the registered classloaders. 13369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 13469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public Map getRegisteredCLs() { 13569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal clearUnregisteredClassLoaders(); 13669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return registeredCLs; 13769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 13869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 13969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 14069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * This method will check to see if a register classloader has been 14169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * undeployed (as in JBoss) 14269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 14369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void clearUnregisteredClassLoaders() { 14469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ArrayList toUnregister = null; 14569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal synchronized (registeredCLs) { 14669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Iterator it = registeredCLs.values().iterator(); 14769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal while (it.hasNext()) { 14869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ScopedClassPool pool = (ScopedClassPool)it.next(); 14969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (pool.isUnloadedClassLoader()) { 15069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal it.remove(); 15169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ClassLoader cl = pool.getClassLoader(); 15269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (cl != null) { 15369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (toUnregister == null) { 15469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal toUnregister = new ArrayList(); 15569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 15669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal toUnregister.add(cl); 15769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 15869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 15969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 16069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (toUnregister != null) { 16169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < toUnregister.size(); i++) { 16269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal unregisterClassLoader((ClassLoader)toUnregister.get(i)); 16369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 16469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 16569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 16669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 16769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 16869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void unregisterClassLoader(ClassLoader cl) { 16969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal synchronized (registeredCLs) { 17069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ScopedClassPool pool = (ScopedClassPool)registeredCLs.remove(cl); 17169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (pool != null) 17269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal pool.close(); 17369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 17469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 17569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 17669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void insertDelegate(ScopedClassPoolRepository delegate) { 17769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // Noop - this is the end 17869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 17969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 18069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void setClassPoolFactory(ScopedClassPoolFactory factory) { 18169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal this.factory = factory; 18269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 18369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 18469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public ScopedClassPoolFactory getClassPoolFactory() { 18569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return factory; 18669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 18769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal} 188