001package org.nuxeo.webengine.gwt.codeserver; 002 003import java.io.IOException; 004import java.net.URI; 005import java.net.URISyntaxException; 006import java.net.URL; 007import java.net.URLClassLoader; 008import java.nio.file.FileSystemNotFoundException; 009import java.nio.file.FileSystems; 010import java.nio.file.Files; 011import java.nio.file.Path; 012import java.nio.file.Paths; 013import java.util.Collections; 014import java.util.HashMap; 015import java.util.Map; 016 017public class CodeServerLoader extends URLClassLoader { 018 019 CodeServerLoader(URL[] jars) { 020 super(jars, CodeServerLoader.class.getClassLoader()); 021 } 022 023 @Override 024 protected java.lang.Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { 025 Class<?> clazz = findLoadedClass(name); 026 if (clazz != null) { 027 return clazz; 028 } 029 030 if (name.equals(CodeServerLauncher.class.getName())) { 031 return getParent().loadClass(name); 032 } 033 034 if (name.equals(CodeServerWrapper.class.getName())) { 035 try { 036 return reloadClass(CodeServerWrapper.class); 037 } catch (URISyntaxException | IOException cause) { 038 throw new ClassNotFoundException("Cannot reload wrapper in gwt dev class loader", cause); 039 } 040 } 041 try { 042 return ClassLoader.getSystemClassLoader().loadClass(name); 043 } catch (ClassNotFoundException cause) { 044 ; 045 } 046 synchronized (getClassLoadingLock(name)) { 047 clazz = findClass(name); 048 if (clazz != null) { 049 return clazz; 050 } 051 } 052 throw new ClassNotFoundException("Cannot find " + name + " in gwt class loader"); 053 }; 054 055 Class<?> reloadClass(Class<?> clazz) throws URISyntaxException, IOException { 056 URI location = clazz.getResource(clazz.getSimpleName().concat(".class")).toURI(); 057 byte[] content = Files.readAllBytes(getPath(location)); 058 return defineClass(clazz.getName(), content, 0, content.length); 059 } 060 061 private Path getPath(URI location) throws IOException { 062 try { 063 return Paths.get(location); 064 } catch (FileSystemNotFoundException cause) { 065 Map<String, Object> env = Collections.emptyMap(); 066 FileSystems.newFileSystem(location, env); 067 return Paths.get(location); 068 } 069 } 070 071 CodeServerLauncher load() throws ReflectiveOperationException { 072 return (CodeServerLauncher) loadClass(CodeServerWrapper.class.getName()).newInstance(); 073 } 074 075}