private String getClassFilename(String name) { String filename = findOnClasspath(name); if (filename != null) return filename; URL res = parent.getResource(getClassRelativePath(name)); return res != null ? getFilename(res) : null; }
private boolean shouldReload(String classname) { boolean couldReload = names.contains(classname) || (!Cls.isRapidoidClass(classname) && !Cls.isJREClass(classname) && !isReloadForbidden(classname) && findOnClasspath(classname) != null); return couldReload && !originalMarkedNotToReload(classname); }
public Class<?> loadClass(String classname) throws ClassNotFoundException { U.notNull(classname, "classname"); Log.debug("Loading class", "name", classname); Class<?> cls = findLoadedClass(classname); if (cls != null) { return cls; } if (shouldReload(classname)) { try { Class<?> reloaded = findClass(classname); return !reloadVeto(reloaded) ? reloaded : super.loadClass(classname); } catch (ClassNotFoundException e) { Class<?> fallbackClass = super.loadClass(classname); Log.debug("Couldn't reload class, fallback load", "name", classname); return fallbackClass; } } else { return super.loadClass(classname); } }
@Override protected Class<?> findClass(String name) throws ClassNotFoundException { String filename = getClassFilename(name); if (filename != null) { try { return super.findClass(name); } catch (ClassNotFoundException e) { Log.debug("Hot swap", "file", filename); return reload(name, filename); } } else { return super.findClass(name); } }
private String findOnClasspath(String name) { for (String dir : classpath) { File classFile = new File(dir, getClassRelativePath(name)); if (classFile.exists()) { return classFile.getAbsolutePath(); } } return null; }
public static ClassReloader createClassLoader(Collection<String> classpath, Predicate<String> veto) { Log.debug("Creating class loader", "classpath", classpath); ClassLoader parentClassLoader = ClassReloader.class.getClassLoader(); return new ClassReloader(classpath, parentClassLoader, U.list(), veto); }
public static synchronized List<Class<?>> reloadClasses(Collection<String> classpath, List<String> classnames, Predicate<String> veto) { ClassReloader classLoader = Reload.createClassLoader(classpath, veto); List<Class<?>> classes = U.list(); for (String className : classnames) { try { classes.add(classLoader.loadClass(className)); } catch (Throwable e) { Log.debug("Couldn't reload class!", "error", e); } } return classes; }
private Class<?> reload(String name, String filename) throws ClassNotFoundException { Log.debug("Reloading class", "name", name, "filename", filename); for (int i = 0; i < 100; i++) { try { byte[] classData = IO.loadBytes(filename); return defineClass(name, classData, 0, classData.length); } catch (ClassFormatError e) { // wait some time and retry again... U.sleep(50); } } throw new ClassNotFoundException("Couldn't find class: " + name); }