/************************************************************************** * Copyright (c) 2001 by Punch Telematix. All rights reserved. * * * * Redistribution and use in source and binary forms, with or without * * modification, are permitted provided that the following conditions * * are met: * * 1. Redistributions of source code must retain the above copyright * * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * * notice, this list of conditions and the following disclaimer in the * * documentation and/or other materials provided with the distribution. * * 3. Neither the name of Punch Telematix nor the names of * * other contributors may be used to endorse or promote products * * derived from this software without specific prior written permission.* * * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * * IN NO EVENT SHALL PUNCH TELEMATIX OR OTHER CONTRIBUTORS BE LIABLE * * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * **************************************************************************/ package java.rmi.server; import java.net.*; import java.lang.ref.*; import java.util.Hashtable; import java.util.Iterator; import java.util.Map; import java.util.StringTokenizer; import java.util.TimerTask; import java.util.Vector; import java.security.*; import wonka.vm.SystemTimer; public class RMIClassLoader { private RMIClassLoader(){} static final String DEFAULT_CODEBASE; private static final boolean USE_CODEBASE_ONLY; static final Hashtable classLoaders; static ReferenceQueue queue; static { boolean b = false; classLoaders = new Hashtable(11); DEFAULT_CODEBASE = System.getProperty("java.rmi.server.codebase"); try { b = Boolean.getBoolean("java.rmi.server.useCodebaseOnly"); } catch(RuntimeException rt){} USE_CODEBASE_ONLY = b && (DEFAULT_CODEBASE != null); } public static String getClassAnnotation(final Class cl) { return(String) AccessController.doPrivileged(new PrivilegedAction(){ public Object run(){ ProtectionDomain pd = cl.getProtectionDomain(); if(pd != null){ CodeSource cs = pd.getCodeSource(); if(cs != null){ return cs.getLocation().toString(); } } return DEFAULT_CODEBASE; } }); } public static ClassLoader getClassLoader(String codebase) throws MalformedURLException, SecurityException { synchronized(classLoaders){ WeakReference ref = (WeakReference) classLoaders.get(codebase); if(ref != null){ ClassLoader cl = (ClassLoader)ref.get(); if(cl != null){ return cl; } } Vector v = new Vector(); StringTokenizer st = new StringTokenizer(codebase); while(st.hasMoreTokens()){ v.add(new URL(st.nextToken())); } ClassLoader cl = new URLClassLoader((URL[]) v.toArray(new URL[v.size()])); if(queue == null){ queue = new ReferenceQueue(); new CleanupTask(); } classLoaders.put(codebase, new WeakReference(cl,queue)); return cl; } } /** ** @deprecated */ public static Object getSecurityContext(ClassLoader loader) { throw new wonka.vm.DeprecatedMethodError("RMIClassLoader.getSecurityContext(java.lang.ClassLoader) is depracted"); } /** ** @deprecated */ public static Class loadClass(String name) throws MalformedURLException, ClassNotFoundException { throw new wonka.vm.DeprecatedMethodError("RMIClassLoader.loadClass(java.lang.String) is depracted"); } public static Class loadClass(String codebase, String name) throws MalformedURLException, ClassNotFoundException { if(USE_CODEBASE_ONLY){ codebase = DEFAULT_CODEBASE; } return Class.forName(name, true, getClassLoader(codebase)); } public static Class loadClass(URL codebase, String name) throws MalformedURLException, ClassNotFoundException { return loadClass(codebase.toString(), name); } private static class CleanupTask extends TimerTask { public CleanupTask(){ SystemTimer.scheduleSystemTask(this, 10000); } public void run(){ Reference ref = queue.poll(); while(ref != null){ synchronized(classLoaders){ Iterator it = classLoaders.entrySet().iterator(); try { Map.Entry entry = (Map.Entry)it.next(); if(ref == entry.getValue()){ it.remove(); } } catch(java.util.NoSuchElementException nsee){} if(classLoaders.size() == 0){ queue = null; this.cancel(); break; } } ref = queue.poll(); } } } }