RenderClassLoader extends ClassLoader { @NotNull protected Class<?> loadClassFromNonProjectDependency(@NotNull String name) throws ClassNotFoundException { UrlClassLoader jarClassLoaders; synchronized (myJarClassLoaderLock) { jarClassLoaders = myJarClassLoader.get(); } myInsideJarClassLoader = true; try (InputStream is = jarClassLoaders.getResourceAsStream(name.replace('.', '/') + SdkConstants.DOT_CLASS)) { if (is == null) { throw new ClassNotFoundException(name); } byte[] data = ByteStreams.toByteArray(is); if (!isValidClassFile(data)) { throw new ClassFormatError(name); } byte[] rewritten = ClassConverter.rewriteClass(data, DEFAULT_TRANSFORMS); return defineClassAndPackage(name, rewritten, 0, rewritten.length); } catch (IOException | ClassNotFoundException e) { LOG.debug(e); } finally { myInsideJarClassLoader = false; } if (LOG.isDebugEnabled()) LOG.debug(String.format("ClassNotFoundException(%s)", name)); throw new ClassNotFoundException(name); } RenderClassLoader(@Nullable ClassLoader parent);   }
@Test public void testRemovingJarFile() throws IOException, ClassNotFoundException { ourLoggerInstance = new DefaultLogger("") { @Override public void error(@NonNls String message, @Nullable Throwable t, @NonNls @NotNull String... details) { fail("Logger shouldn't receive any error calls"); } }; File jarSource = new File(AndroidTestBase.getTestDataPath(), "rendering/renderClassLoader/lib.jar"); File testJarFile = File.createTempFile("RenderClassLoader", ".jar"); FileUtil.copy(jarSource, testJarFile); URL testJarFileUrl = testJarFile.toURI().toURL(); RenderClassLoader loader = new RenderClassLoader(this.getClass().getClassLoader()) { @Override protected List<URL> getExternalJars() { return ImmutableList.of(testJarFileUrl); } }; loader.loadClassFromNonProjectDependency("com.myjar.MyJarClass"); assertTrue(testJarFile.delete()); try { loader.loadClassFromNonProjectDependency("com.myjar.MyJarClass"); fail("Class should be available anymore"); } catch (ClassNotFoundException ignore) { } }