public static ClassLoader reloader() { Predicate<String> veto = ReloadUtil::isReloadForbidden; return Reload.createClassLoader(veto); }
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 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 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; }
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); } }
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); }
@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 boolean originalMarkedNotToReload(String classname) { Class<?> cls = Cls.getClassIfExists(classname); return cls != null && reloadVeto(cls); }
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); }
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); }
protected void reload() { Set<String> filenames = U.set(); filenames.addAll(createdFilenames); filenames.addAll(modifiedFilenames); Log.debug("Detected changes in classes", "created", createdFilenames, "modified", modifiedFilenames, "deleted", deletedFilenames); try { List<String> classnames = filenamesToClassnames(filenames); List<Class<?>> classes = Reload.reloadClasses(folders, classnames, veto); refresher.refresh(classes, filenamesToClassnames(deletedFilenames)); } catch (Exception e) { e.printStackTrace(); } }
public static ClassReloader createClassLoader(Predicate<String> veto) { return createClassLoader(ClasspathUtil.getClasspathFolders(), veto); }
public static ClassLoader reloader() { return Reload.createClassLoader(); }