public MemoryFileManager(ClassLoader classLoader, JavaFileManager fileManager) { super(fileManager); helper = new PackageHelper(classLoader); }
public byte[] getClassBytes(String name) { return fileManager.getCompiledClass(name); } }
public String resolveMainClassName() { return javaSourceContext.getClassName(); }
@Override public Verticle createVerticle(String verticleName, ClassLoader classLoader) throws Exception { verticleName = VerticleFactory.removePrefix(verticleName); Class clazz; if (verticleName.endsWith(".java")) { CompilingClassLoader compilingLoader = new CompilingClassLoader(classLoader, verticleName); String className = compilingLoader.resolveMainClassName(); clazz = compilingLoader.loadClass(className); } else { clazz = classLoader.loadClass(verticleName); } return (Verticle) clazz.newInstance(); }
private String createClassOutsideClasspath(String className) throws Exception { File dir = Files.createTempDirectory("vertx").toFile(); dir.deleteOnExit(); File source = new File(dir, className + ".java"); Files.write(source.toPath(), ("public class " + className + " extends io.vertx.core.AbstractVerticle {} ").getBytes()); URLClassLoader loader = new URLClassLoader(new URL[]{dir.toURI().toURL()}, Thread.currentThread().getContextClassLoader()); CompilingClassLoader compilingClassLoader = new CompilingClassLoader(loader, className + ".java"); compilingClassLoader.loadClass(className); byte[] bytes = compilingClassLoader.getClassBytes(className); assertNotNull(bytes); File classFile = new File(dir, className + ".class"); Files.write(classFile.toPath(), bytes); return dir.getAbsolutePath(); }
public CompilingClassLoader(ClassLoader loader, String sourceName) { super(loader); URL resource = getResource(sourceName); if (resource == null) { throw new RuntimeException("Resource not found: " + sourceName); this.javaSourceContext = new JavaSourceContext(sourceFile); standardFileManager.setLocation(StandardLocation.SOURCE_PATH, Collections.singleton(javaSourceContext.getSourceRoot())); fileManager = new MemoryFileManager(loader, standardFileManager); JavaFileObject javaFile = standardFileManager.getJavaFileForInput(StandardLocation.SOURCE_PATH, resolveMainClassName(), Kind.SOURCE); JavaCompiler.CompilationTask task = javaCompiler.getTask(null, fileManager, diagnostics, COMPILER_OPTIONS, null, Collections.singleton(javaFile)); boolean valid = task.call();
@Override protected Class<?> findClass(String name) throws ClassNotFoundException { byte[] bytecode = getClassBytes(name); if (bytecode == null) { throw new ClassNotFoundException(name); } return defineClass(name, bytecode, 0, bytecode.length); }
public List<JavaFileObject> find(String packageName) throws IOException { String javaPackageName = packageName.replaceAll("\\.", "/"); List<JavaFileObject> result = new ArrayList<>(); Enumeration<URL> urlEnumeration = classLoader.getResources(javaPackageName); while (urlEnumeration.hasMoreElements()) { URL resource = urlEnumeration.nextElement(); //Need to urldecode it too, since bug in JDK URL class which does not url decode it, so if it contains spaces you are screwed final File directory = new File(decodeURIComponent(resource.getFile(), false)); if (directory.isDirectory()) { result.addAll(browseDir(packageName, directory)); } else { result.addAll(browseJar(resource)); } } return result; }
public String getName() { return toUri().getPath(); }
private static List<JavaFileObject> browseDir(String packageName, File directory) { List<JavaFileObject> result = new ArrayList<>(); for (File childFile : directory.listFiles()) { if (childFile.isFile() && childFile.getName().endsWith(CLASS_FILE)) { String binaryName = packageName + "." + childFile.getName().replaceAll(CLASS_FILE + "$", ""); result.add(new CustomJavaFileObject(childFile.toURI(), JavaFileObject.Kind.CLASS, binaryName)); } } return result; }
public Writer openWriter() throws IOException { return new OutputStreamWriter(openOutputStream()); }
@Override public String inferBinaryName(Location location, JavaFileObject file) { if (file instanceof CustomJavaFileObject) { return ((CustomJavaFileObject) file).binaryName(); } else { return super.inferBinaryName(location, file); } }
@Override public Iterable<JavaFileObject> list(Location location, String packageName, Set<JavaFileObject.Kind> kinds, boolean recurse) throws IOException { if (location == StandardLocation.CLASS_PATH && kinds.contains(JavaFileObject.Kind.CLASS)) { return helper.find(packageName); } return super.list(location, packageName, kinds, recurse); } }
public JavaSourceContext(File file) { String packageName = parsePackage(file); File rootDirectory = file.getParentFile(); if (packageName != null) { String[] pathTokens = packageName.split("\\."); for(int i = pathTokens.length - 1; i >= 0; i--) { String token = pathTokens[i]; if (!token.equals(rootDirectory.getName())) { throw new RuntimeException("Package structure does not match directory structure: " + token + " != " + rootDirectory.getName()); } rootDirectory = rootDirectory.getParentFile(); } } sourceRoot = rootDirectory; String fileName = file.getName(); String className = fileName.substring(0, fileName.length() - Kind.SOURCE.extension.length()); if (packageName != null) { className = packageName + '.' + className; } this.className = className; }
public MemoryFileManager(ClassLoader classLoader, JavaFileManager fileManager) { super(fileManager); helper = new PackageHelper(classLoader); }
public byte[] getClassBytes(String name) { return fileManager.getCompiledClass(name); } }
public String resolveMainClassName() { return javaSourceContext.getClassName(); }
@Override public String toString() { return getClass().getName() + '[' + toUri() + ']'; } }
private static List<JavaFileObject> browseJar(URL packageFolderURL) { List<JavaFileObject> result = new ArrayList<>(); try { String jarUri = packageFolderURL.toExternalForm().split("!")[0]; JarURLConnection jarConn = (JarURLConnection) packageFolderURL.openConnection(); String rootEntryName = jarConn.getEntryName(); int rootEnd = rootEntryName.length() + 1; Enumeration<JarEntry> entryEnum = jarConn.getJarFile().entries(); while (entryEnum.hasMoreElements()) { JarEntry jarEntry = entryEnum.nextElement(); String name = jarEntry.getName(); if (name.startsWith(rootEntryName) && name.indexOf('/', rootEnd) == -1 && name.endsWith(CLASS_FILE)) { String binaryName = name.replaceAll("/", ".").replaceAll(CLASS_FILE + "$", ""); result.add(new CustomJavaFileObject(URI.create(jarUri + "!/" + name), JavaFileObject.Kind.CLASS, binaryName)); } } } catch (Exception e) { throw new RuntimeException(packageFolderURL + " is not a JAR file", e); } return result; } }