package net.sourceforge.pain; import net.sourceforge.pain.plugin.*; import net.sourceforge.pain.util.*; import java.io.*; public class LogicLoadingManager { private static final String EVENTS_PACKAGE = "net.sourceforge.pain.logic.event."; private static int counter = 0;// for debug use /** path where to look for logic class files*/ protected String dirPath; /** classloaders by classname */ private LogicClassLoader loader = new LogicClassLoader(); protected LogicLoadingManager(String dirPath) { this.dirPath = dirPath; } public synchronized Class provideClass(String className) throws ClassNotFoundException { Class c = loader._findLoadedClass(className); if (c != null) { Log.debug("findLoadedClass works!:" + className); return c; } // net.sourceforge.pain.logic.Event is not reloadable system class! if (!className.startsWith("net.sourceforge.pain.logic.") || className.equals("net.sourceforge.pain.logic.Event")) { if (isPluginImpl(className)) { Log.debug("Asking plugin from LOGIC LOADER:" + className); return Core.getPluginManager().loadClassByPluginClassloader(null, className); } try { c = Class.forName(className); } catch (LinkageError error) { if (error instanceof NoClassDefFoundError && error.getMessage().indexOf("wrong name:") > 0) { // case insensitive filesystem -> we will hide this errors } else { // this will not stop server but will panic! Log.error("PANIC!!!", error); } throw new ClassNotFoundException("Error during systen class loading!", error); } Log.debug("findSystemClass works!:" + className); return c; } Log.debug("LLM:asking logic class:" + className); c = loader.defineClassFromFile(className); return c; } private static boolean isPluginImpl(String className) { return (className.startsWith(PluginManager.PLUGINS_HOME) && className.lastIndexOf('.') > PluginManager.PLUGINS_HOME_LENGTH); } public synchronized void reload() { loader = new LogicClassLoader(); System.gc(); } public ClassLoader getActiveClassLoader() { return loader; } public Class provideEventClass(String eventClassSuffix) throws ClassNotFoundException { return provideClass(EVENTS_PACKAGE + eventClassSuffix); } public class LogicClassLoader extends ClassLoader { int number = counter; protected LogicClassLoader() { } public synchronized Class loadClass(String className) throws ClassNotFoundException { Log.debug("LOGIC LOADER[" + number + "]: ask load:" + className); return provideClass(className); } protected Class defineClassFromFile(String className) throws ClassNotFoundException { try { byte[] data = Core.getFileData(dirPath + "/" + className.replace('.', '/') + ".class"); return super.defineClass(className, data, 0, data.length); } catch (IOException e) { Log.warn("Can't load class file! " + e.getMessage()); throw new ClassNotFoundException("Class File Not Found:" + dirPath + "/" + className + ".class"); } } protected Class _findLoadedClass(String className) { return super.findLoadedClass(className); } protected void finalize() { Log.debug("LOGIC LOADER[" + number + "]:finalizing"); } } }