@Override public void handleChanges(Collection<WatchServiceFileSystemWatcher.FileChangeEvent> changes) { try { List<AddedClass> addedClasses = new ArrayList<>(); List<ClassDefinition> changedClasses = new ArrayList<>(); for (WatchServiceFileSystemWatcher.FileChangeEvent change : changes) { if (change.getType() == WatchServiceFileSystemWatcher.FileChangeEvent.Type.ADDED) { try (FileInputStream in = new FileInputStream(change.getFile())) { byte[] bytes = FileReader.readFileBytes(in); ClassFile file = new ClassFile(new DataInputStream(new ByteArrayInputStream(bytes))); addedClasses.add(new AddedClass(file.getName(), bytes, classLoader)); } } else if (change.getType() == WatchServiceFileSystemWatcher.FileChangeEvent.Type.MODIFIED) { String hash = hashes.get(change.getFile().getCanonicalPath()); if (hash == null) { // class is not loaded yet continue; } try (FileInputStream in = new FileInputStream(change.getFile())) { byte[] bytes = FileReader.readFileBytes(in); if (!hash.equals(MD5.md5(bytes))) { ClassFile file = new ClassFile(new DataInputStream(new ByteArrayInputStream(bytes))); changedClasses.add( new ClassDefinition(classLoader.loadClass(file.getName()), bytes)); } } } } Agent.redefine( changedClasses.toArray(new ClassDefinition[changedClasses.size()]), addedClasses.toArray(new AddedClass[addedClasses.size()])); } catch (Exception e) { e.printStackTrace(); } }
public static byte[] getIntegrationClass(ClassLoader c, String name) { if (!integrationClassloader.containsKey(c)) { return null; } URL resource = ClassLoader.getSystemClassLoader().getResource(name.replace('.', '/') + ".class"); InputStream in = null; try { in = resource.openStream(); return org.fakereplace.util.FileReader.readFileBytes(resource.openStream()); } catch (Exception e) { throw new RuntimeException(e); } finally { try { if (in != null) { in.close(); } } catch (IOException e) { } } }
public synchronized void addClassFile(String className, ClassLoader classLoader) { if (classLoader == null) { return; } URL resource = classLoader.getResource(className.replace(".", "/") + ".class"); if (resource == null) { return; } File file = new File(resource.getFile()); if (!file.exists()) { return; } int parentCount = 1; for (int i = 0; i < className.length(); ++i) { if (className.charAt(i) == '.' || className.charAt(i) == '/') { parentCount++; } } try (InputStream in = resource.openStream()) { hashes.put(file.getCanonicalPath(), MD5.md5(FileReader.readFileBytes(in))); } catch (IOException e) { e.printStackTrace(); return; } for (int i = 0; i < parentCount; ++i) { file = file.getParentFile(); } if (registered.contains(file)) { return; } registered.add(file); Callback callback = callbacks.get(classLoader); if (callback == null) { callbacks.put(classLoader, callback = new Callback(classLoader)); } watcher.watchPath(file, callback); }
@Override public Iterable<JavaFileObject> list( Location location, String packageName, Set<Kind> kinds, boolean recurse) throws IOException { if (location == StandardLocation.PLATFORM_CLASS_PATH) { return standardJavaFileManager.list(location, packageName, kinds, recurse); } List<JavaFileObject> ret = new ArrayList<>(); if (kinds.contains(Kind.CLASS) && location.equals(StandardLocation.CLASS_PATH)) { if (classLoader instanceof ModuleClassLoader) { ModuleClassLoader mcl = (ModuleClassLoader) classLoader; final String packageWithSlashes = packageName.replace(".", "/"); try { Iterator<Resource> resources = mcl.getModule() .iterateResources( new PathFilter() { @Override public boolean accept(String path) { if (recurse) { return path.startsWith(packageWithSlashes); } else { return path.equals(packageWithSlashes); } } }); while (resources.hasNext()) { Resource res = resources.next(); if (!res.getName().endsWith(".class")) { continue; } String binaryName = res.getName().replace("/", ".").substring(0, res.getName().length() - 6); try { ret.add( new ZipJavaFileObject( org.fakereplace.util.FileReader.readFileBytes(res.openStream()), binaryName, res.getURL().toURI())); } catch (URISyntaxException e) { e.printStackTrace(); } } } catch (ModuleLoadException e) { e.printStackTrace(); } } else { URL res = classLoader.getResource(packageName.replace(".", "/")); if (res != null) { if (res.getProtocol().equals("file")) { Path dirPath = Paths.get(res.getFile()); listDir(packageName, dirPath, recurse, ret); } else if (res.getProtocol().equals("jar")) { JarURLConnection connection = (JarURLConnection) res.openConnection(); Enumeration<JarEntry> entryEnum = connection.getJarFile().entries(); while (entryEnum.hasMoreElements()) { JarEntry entry = entryEnum.nextElement(); String name = entry.getName(); if (name.endsWith(".class") && !entry.isDirectory()) { if (name.startsWith(packageName.replace(".", "/"))) { String rem = name.substring(packageName.length()); if (rem.startsWith("/")) { rem = rem.substring(1); } if (!recurse) { if (rem.contains("/")) { continue; } } String binaryName = entry .getName() .replace("/", ".") .substring(0, entry.getName().length() - 6); try { URI uri = new URI(res.toExternalForm() + "/" + rem); ret.add( new ZipJavaFileObject( org.fakereplace.util.FileReader.readFileBytes( uri.toURL().openStream()), binaryName, uri)); } catch (Exception e) { e.printStackTrace(); } } } } } else { System.err.println( "Could not find package " + packageName + " in " + classLoader + " unknown protocol " + res.getProtocol()); } } else { return standardJavaFileManager.list(location, packageName, kinds, recurse); } } } else { return standardJavaFileManager.list(location, packageName, kinds, recurse); } return ret; }