@Override public Class<?> loadClass(String name) throws ClassNotFoundException { Class<?> clazz = findLoadedClass(name); if (clazz == null) { try { clazz = parent.loadClass(name); } catch (ClassNotFoundException e) { return findClass(name); } if (loadLocally(clazz)) { clazz = findClass(name); } return clazz; } else { return clazz; } }
@Override public URL getResource(String name) { URL url = findResource(name); if (url == null) { url = super.getResource(name); } return url; } }
private Iterator<Class<?>> getDirectDependencies(Class<?> type) { HashSet<Class<?>> dependencies = new HashSet<Class<?>>(); resolveDirectDependencies(type, dependencies); return dependencies.iterator(); }
@Test public void testNotFound() { LiveClassLoader loader = new LiveClassLoader(new URL[0], Thread.currentThread().getContextClassLoader()); try { loader.loadClass("foo.bar"); fail(); } catch (ClassNotFoundException ok) { } }
try { String resourceName = clazz.getName().replace('.', '/') + ".class"; URL resource = findResource(resourceName); if (resource == null) { for (Iterator<Class<?>> dependencies = getDirectDependencies(clazz);dependencies.hasNext();) { Class<?> dependency = dependencies.next(); if (loadLocally(stack, dependency)) { return true;
void init() { if (local == null) try { compilerAssert1.assertCompile(); compilerAssert2.assertCompile(); parent = new URLClassLoader(new URL[]{compilerAssert1.getClassOutput().getURL()}); local = new LiveClassLoader(new URL[]{compilerAssert2.getClassOutput().getURL()}, parent); } catch (IOException e) { throw failure(e); } }
private void resolveGenericDirectDependencies(Type type, HashSet<Class<?>> dependencies) { if (type instanceof Class<?>) { dependencies.add((Class<?>)type); } else if (type instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType)type; for (Type typeArg : parameterizedType.getActualTypeArguments()) { resolveGenericDirectDependencies(typeArg, dependencies); } } else if (type instanceof WildcardType) { WildcardType wildcardType = (WildcardType)type; for (Type upperBound : wildcardType.getUpperBounds()) { resolveGenericDirectDependencies(upperBound, dependencies); } for (Type lowerBound : wildcardType.getLowerBounds()) { resolveGenericDirectDependencies(lowerBound, dependencies); } } else { throw new UnsupportedOperationException("Type " + type + " not yet supported"); } }
Class<?> assertLoadedBy(ClassLoader expectedLoader, String name) { try { Class<?> clazz = local.loadClass(name); assertSame(expectedLoader, clazz.getClassLoader()); return clazz; } catch (ClassNotFoundException e) { throw failure(e); } }
private boolean loadLocally(Class<?> clazz) { return loadLocally(new LinkedList<Class<?>>(), clazz); } /**
@Test public void testResource() throws IOException { Context ctx = new Context("common.live.resource"); ctx.init(); // assertEquals("bar", Tools.read(ctx.local.getResource("common/live/resource/foo.txt"))); // File dir = new File(ctx.compilerAssert2.getClassOutput().getRoot(), "common/live/resource"); assertTrue(dir.mkdirs()); File f = new File(dir, "foo.txt"); new FileWriter(f).append("bar_").close(); assertEquals("bar_", Tools.read(ctx.local.getResource("common/live/resource/foo.txt"))); } }
@Test public void testNotFound() { LiveClassLoader loader = new LiveClassLoader(new URL[0], Thread.currentThread().getContextClassLoader()); try { loader.loadClass("foo.bar"); fail(); } catch (ClassNotFoundException ok) { } }
try { String resourceName = clazz.getName().replace('.', '/') + ".class"; URL resource = findResource(resourceName); if (resource == null) { for (Iterator<Class<?>> dependencies = getDirectDependencies(clazz);dependencies.hasNext();) { Class<?> dependency = dependencies.next(); if (loadLocally(stack, dependency)) { return true;
void init() { if (local == null) try { compilerAssert1.assertCompile(); compilerAssert2.assertCompile(); parent = new URLClassLoader(new URL[]{compilerAssert1.getClassOutput().getURL()}); local = new LiveClassLoader(new URL[]{compilerAssert2.getClassOutput().getURL()}, parent); } catch (IOException e) { throw failure(e); } }
private void resolveDirectDependencies(Class<?> clazz, HashSet<Class<?>> dependencies) { for (Field field : clazz.getDeclaredFields()) { resolveGenericDirectDependencies(field.getGenericType(), dependencies); } for (Constructor<?> ctor : clazz.getDeclaredConstructors()) { for (Type genericParameterType : ctor.getGenericParameterTypes()) { resolveGenericDirectDependencies(genericParameterType, dependencies); } } for (Method method : clazz.getDeclaredMethods()) { resolveGenericDirectDependencies(method.getGenericReturnType(), dependencies); for (Type genericParameterType : method.getGenericParameterTypes()) { resolveGenericDirectDependencies(genericParameterType, dependencies); } } Type genericSuperClass = clazz.getGenericSuperclass(); if (genericSuperClass != null) { resolveGenericDirectDependencies(genericSuperClass, dependencies); } for (Type genericInterface : clazz.getGenericInterfaces()) { resolveGenericDirectDependencies(genericInterface, dependencies); } }
Class<?> assertLoadedBy(ClassLoader expectedLoader, String name) { try { Class<?> clazz = local.loadClass(name); assertSame(expectedLoader, clazz.getClassLoader()); return clazz; } catch (ClassNotFoundException e) { throw failure(e); } }
private boolean loadLocally(Class<?> clazz) { return loadLocally(new LinkedList<Class<?>>(), clazz); } /**
@Test public void testResource() throws IOException { Context ctx = new Context("common.live.resource"); ctx.init(); // assertEquals("bar", Tools.read(ctx.local.getResource("common/live/resource/foo.txt"))); // File dir = new File(ctx.compilerAssert2.getClassOutput().getRoot(), "common/live/resource"); assertTrue(dir.mkdirs()); File f = new File(dir, "foo.txt"); new FileWriter(f).append("bar_").close(); assertEquals("bar_", Tools.read(ctx.local.getResource("common/live/resource/foo.txt"))); } }
@Override public Class<?> loadClass(String name) throws ClassNotFoundException { Class<?> clazz = findLoadedClass(name); if (clazz == null) { try { clazz = parent.loadClass(name); } catch (ClassNotFoundException e) { return findClass(name); } if (loadLocally(clazz)) { clazz = findClass(name); } return clazz; } else { return clazz; } }
this.classLoader = new LiveClassLoader(new URL[]{classOutput.getURL()}, baseClassLoader); this.classes = classOutput; this.snapshot = next;
private void resolveGenericDirectDependencies(Type type, HashSet<Class<?>> dependencies) { if (type instanceof Class<?>) { dependencies.add((Class<?>)type); } else if (type instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType)type; for (Type typeArg : parameterizedType.getActualTypeArguments()) { resolveGenericDirectDependencies(typeArg, dependencies); } } else if (type instanceof WildcardType) { WildcardType wildcardType = (WildcardType)type; for (Type upperBound : wildcardType.getUpperBounds()) { resolveGenericDirectDependencies(upperBound, dependencies); } for (Type lowerBound : wildcardType.getLowerBounds()) { resolveGenericDirectDependencies(lowerBound, dependencies); } } else { throw new UnsupportedOperationException("Type " + type + " not yet supported"); } }