1/* 2 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24import javax.tools.JavaCompiler; 25import javax.tools.StandardJavaFileManager; 26import javax.tools.StandardLocation; 27import javax.tools.ToolProvider; 28import java.io.IOException; 29import java.io.UncheckedIOException; 30import java.nio.file.FileVisitResult; 31import java.nio.file.Files; 32import java.nio.file.Path; 33import java.nio.file.SimpleFileVisitor; 34import java.nio.file.attribute.BasicFileAttributes; 35import java.util.ArrayList; 36import java.util.Arrays; 37import java.util.List; 38import java.util.stream.Collectors; 39import java.util.stream.Stream; 40 41public final class CompilerUtils { 42 private CompilerUtils() { } 43 44 /** 45 * Compile all the java sources in {@code <source>/**} to 46 * {@code <destination>/**}. The destination directory will be created if 47 * it doesn't exist. 48 * 49 * All warnings/errors emitted by the compiler are output to System.out/err. 50 * 51 * @return true if the compilation is successful 52 * 53 * @throws IOException if there is an I/O error scanning the source tree or 54 * creating the destination directory 55 */ 56 public static boolean compile(Path source, Path destination, String... options) 57 throws IOException 58 { 59 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 60 StandardJavaFileManager jfm = compiler.getStandardFileManager(null, null, null); 61 62 List<Path> sources 63 = Files.find(source, Integer.MAX_VALUE, 64 (file, attrs) -> (file.toString().endsWith(".java"))) 65 .collect(Collectors.toList()); 66 67 Files.createDirectories(destination); 68 jfm.setLocationFromPaths(StandardLocation.CLASS_OUTPUT, 69 Arrays.asList(destination)); 70 71 List<String> opts = Arrays.asList(options); 72 JavaCompiler.CompilationTask task 73 = compiler.getTask(null, jfm, null, opts, null, 74 jfm.getJavaFileObjectsFromPaths(sources)); 75 76 return task.call(); 77 } 78 79 /** 80 * Compile the specified module from the given module sourcepath 81 * 82 * All warnings/errors emitted by the compiler are output to System.out/err. 83 * 84 * @return true if the compilation is successful 85 * 86 * @throws IOException if there is an I/O error scanning the source tree or 87 * creating the destination directory 88 */ 89 public static boolean compileModule(Path source, Path destination, 90 String moduleName, String... options) { 91 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 92 StandardJavaFileManager jfm = compiler.getStandardFileManager(null, null, null); 93 94 try { 95 Files.createDirectories(destination); 96 jfm.setLocationFromPaths(StandardLocation.CLASS_OUTPUT, 97 Arrays.asList(destination)); 98 } catch (IOException e) { 99 throw new UncheckedIOException(e); 100 } 101 102 Stream<String> opts = Arrays.stream(new String[] { 103 "--module-source-path", source.toString(), "-m", moduleName 104 }); 105 List<String> javacOpts = Stream.concat(opts, Arrays.stream(options)) 106 .collect(Collectors.toList()); 107 JavaCompiler.CompilationTask task 108 = compiler.getTask(null, jfm, null, javacOpts, null, null); 109 return task.call(); 110 } 111 112 113 public static void cleanDir(Path dir) throws IOException { 114 if (Files.notExists(dir)) return; 115 116 Files.walkFileTree(dir, new SimpleFileVisitor<Path>() { 117 @Override 118 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) 119 throws IOException 120 { 121 Files.delete(file); 122 return FileVisitResult.CONTINUE; 123 } 124 @Override 125 public FileVisitResult postVisitDirectory(Path dir, IOException e) 126 throws IOException 127 { 128 if (e == null) { 129 Files.delete(dir); 130 return FileVisitResult.CONTINUE; 131 } else { 132 // directory iteration failed 133 throw e; 134 } 135 } 136 }); 137 Files.deleteIfExists(dir); 138 } 139} 140