/******************************************************************************* * Copyright (c) 2001, 2010 Mathew A. Nelson and Robocode contributors * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://robocode.sourceforge.net/license/epl-v10.html * * Contributors: * Pavel Savara * - Initial implementation *******************************************************************************/ package net.sf.robocode.core; import java.net.URL; import java.net.URLClassLoader; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.HashSet; import java.util.Set; import java.io.File; /** * @author Pavel Savara (original) */ public class EngineClassLoader extends URLClassLoader { private static final boolean isSecutityOn = !System.getProperty("NOSECURITY", "false").equals("true"); private static Set<String> exclusions = new HashSet<String>(); static { // this will be loaded on system classloader exclusions.add(EngineClassLoader.class.getName()); exclusions.add(Container.class.getName()); exclusions.add(RobocodeMainBase.class.getName()); // .NET proxies and their interfaces must be loaded in system class loader in order to call native methods exclusions.add("net.sf.robocode.host.IHost"); exclusions.add("net.sf.robocode.host.IHostManager"); exclusions.add("net.sf.robocode.host.proxies.IHostingRobotProxy"); exclusions.add("net.sf.robocode.peer.IRobotPeer"); exclusions.add("net.sf.robocode.repository.IRobotRepositoryItem"); exclusions.add("net.sf.robocode.repository.RobotType"); exclusions.add("net.sf.robocode.host.RobotStatics"); exclusions.add("net.sf.robocode.peer.BadBehavior"); exclusions.add("net.sf.robocode.dotnet.host.DotnetHost"); exclusions.add("net.sf.robocode.dotnet.repository.root.DllRootHelper"); exclusions.add("net.sf.robocode.dotnet.nhost.ModuleN"); exclusions.add("net.sf.robocode.host.proxies.__IHostingRobotProxy"); } public static void addExclusion(String classFullName) { exclusions.add(classFullName); } public EngineClassLoader(ClassLoader parent) { super(Container.findJars(File.separator + "robocode."), parent); } public EngineClassLoader(URL[] urls, ClassLoader parent) { super(urls, parent); } public synchronized void addURL(URL url) { super.addURL(url); } public synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { if (name.startsWith("java.lang")) { // we always delegate java.lang stuff to parent loader return super.loadClass(name, resolve); } if (isSecutityOn && isEngineClass(name)) { // yes, it is in engine's classpath // we load it localy return loadEngineClass(name, resolve); } // it is robot API // or java class // or security is off // so we delegate to parent classloader return super.loadClass(name, resolve); } private Class<?> loadEngineClass(String name, boolean resolve) throws ClassNotFoundException { Class<?> result = findLoadedClass(name); if (result == null) { result = findClass(name); } if (resolve) { resolveClass(result); } return result; } private boolean isEngineClass(String name) { if (name.startsWith("net.sf.robocode") || name.startsWith("robocode.control")) { if (exclusions.contains(name)) { return false; } // try to find it in engine's classpath // this is URL, don't change to File.pathSeparator final String path = name.replace('.', '/').concat(".class"); return AccessController.doPrivileged(new PrivilegedAction<Boolean>() { public Boolean run() { return findResource(path) != null; } }); } return false; } }