diff options
author | 2017-03-24 01:45:59 +0000 | |
---|---|---|
committer | 2017-03-24 12:19:24 +0000 | |
commit | 58a615c4941e041d68bceeb68b0d77269f6143f5 (patch) | |
tree | 8c29ea7ed1bf58996c8e0b3ef9973446c8407e8b /src/java_tools | |
parent | 4443123db935fafd6f51f9c1f03bba1bc6538a22 (diff) |
Replace ZipOutputFileManager with the standard filemanager and JimFS
Now that the standard filemanager supports nio, there's a better-supported way
to keep the compilation outputs in memory. ZipOutputFileManager doesn't
implement the full filemanager contract, is not compatible with the latest
javac 9's.
--
PiperOrigin-RevId: 151082823
MOS_MIGRATED_REVID=151082823
Diffstat (limited to 'src/java_tools')
7 files changed, 44 insertions, 209 deletions
diff --git a/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/BUILD b/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/BUILD index 5c0a93ac86..d6c2c90f8d 100644 --- a/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/BUILD +++ b/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/BUILD @@ -12,7 +12,6 @@ java_library( ":javac_turbine_compile_request", ":javac_turbine_compile_result", ":javac_turbine_compiler", - ":zip_output_file_manager", ":zip_util", "//src/java_tools/buildjar/java/com/google/devtools/build/buildjar:JarOwner", "//src/java_tools/buildjar/java/com/google/devtools/build/buildjar:javac_options", @@ -40,7 +39,6 @@ java_library( name = "javac_turbine_compile_result", srcs = ["JavacTurbineCompileResult.java"], deps = [ - ":zip_output_file_manager", "//third_party:guava", "//third_party:jsr305", "//third_party/java/jdk/langtools:javac", @@ -54,9 +52,9 @@ java_library( ":javac_turbine_compile_request", ":javac_turbine_compile_result", ":javac_turbine_java_compiler", - ":zip_output_file_manager", "//src/java_tools/buildjar/java/com/google/devtools/build/buildjar/javac/plugins:dependency", "//third_party:guava", + "//third_party:jimfs", "//third_party:jsr305", "//third_party/java/jdk/langtools:javac", ], @@ -75,15 +73,6 @@ java_library( ) java_library( - name = "zip_output_file_manager", - srcs = ["ZipOutputFileManager.java"], - deps = [ - "//third_party:jsr305", - "//third_party/java/jdk/langtools:javac", - ], -) - -java_library( name = "zip_util", srcs = ["ZipUtil.java"], deps = [ diff --git a/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbine.java b/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbine.java index 382e3f4f90..3bdac5fc85 100644 --- a/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbine.java +++ b/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbine.java @@ -27,7 +27,6 @@ import com.google.devtools.build.buildjar.javac.JavacOptions; import com.google.devtools.build.buildjar.javac.plugins.dependency.DependencyModule; import com.google.devtools.build.buildjar.javac.plugins.dependency.DependencyModule.StrictJavaDeps; import com.google.devtools.build.buildjar.javac.plugins.dependency.StrictJavaDepsPlugin; -import com.google.devtools.build.java.turbine.javac.ZipOutputFileManager.OutputFileObject; import com.google.turbine.options.TurbineOptions; import com.google.turbine.options.TurbineOptionsParser; import com.sun.tools.javac.util.Context; @@ -51,7 +50,6 @@ import java.util.List; import java.util.Map; import java.util.regex.Pattern; import java.util.zip.ZipOutputStream; -import javax.tools.StandardLocation; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.ClassWriter; @@ -177,8 +175,7 @@ public class JavacTurbine implements AutoCloseable { if (sources.isEmpty()) { // accept compilations with an empty source list for compatibility with JavaBuilder - emitClassJar( - Paths.get(turbineOptions.outputFile()), ImmutableMap.<String, OutputFileObject>of()); + emitClassJar(Paths.get(turbineOptions.outputFile()), ImmutableMap.of()); dependencyModule.emitDependencyInformation(/*classpath=*/ "", /*successful=*/ true); return Result.OK_WITH_REDUCED_CLASSPATH; } @@ -265,17 +262,14 @@ public class JavacTurbine implements AutoCloseable { } /** Write the class output from a successful compilation to the output jar. */ - private static void emitClassJar(Path outputJar, ImmutableMap<String, OutputFileObject> files) + private static void emitClassJar(Path outputJar, ImmutableMap<String, byte[]> files) throws IOException { try (OutputStream fos = Files.newOutputStream(outputJar); ZipOutputStream zipOut = new ZipOutputStream(new BufferedOutputStream(fos, ZIPFILE_BUFFER_SIZE))) { - for (Map.Entry<String, OutputFileObject> entry : files.entrySet()) { - if (entry.getValue().location != StandardLocation.CLASS_OUTPUT) { - continue; - } + for (Map.Entry<String, byte[]> entry : files.entrySet()) { String name = entry.getKey(); - byte[] bytes = entry.getValue().asBytes(); + byte[] bytes = entry.getValue(); if (bytes == null) { continue; } diff --git a/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbineCompileResult.java b/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbineCompileResult.java index a28f8604ab..23cade9224 100644 --- a/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbineCompileResult.java +++ b/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbineCompileResult.java @@ -16,10 +16,7 @@ package com.google.devtools.build.java.turbine.javac; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableMap; -import com.google.devtools.build.java.turbine.javac.ZipOutputFileManager.OutputFileObject; - import com.sun.tools.javac.util.Context; - import java.io.StringWriter; /** The output from a {@link JavacTurbineCompiler} compilation. */ @@ -29,16 +26,13 @@ class JavacTurbineCompileResult { OK, ERROR } - private final ImmutableMap<String, OutputFileObject> files; + private final ImmutableMap<String, byte[]> files; private final Status status; private final StringWriter sb; private final Context context; JavacTurbineCompileResult( - ImmutableMap<String, OutputFileObject> files, - Status status, - StringWriter sb, - Context context) { + ImmutableMap<String, byte[]> files, Status status, StringWriter sb, Context context) { this.files = files; this.status = status; this.sb = sb; @@ -55,8 +49,8 @@ class JavacTurbineCompileResult { return sb.toString(); } - /** The files produced by the compilation's {@link ZipOutputFileManager}. */ - ImmutableMap<String, OutputFileObject> files() { + /** The files produced by the compilation. */ + ImmutableMap<String, byte[]> files() { return files; } diff --git a/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbineCompiler.java b/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbineCompiler.java index 16dfcb610b..858db23ef2 100644 --- a/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbineCompiler.java +++ b/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbineCompiler.java @@ -14,19 +14,28 @@ package com.google.devtools.build.java.turbine.javac; +import static java.nio.charset.StandardCharsets.UTF_8; + import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.google.common.jimfs.Configuration; +import com.google.common.jimfs.Jimfs; import com.google.devtools.build.buildjar.javac.plugins.dependency.StrictJavaDepsPlugin; import com.google.devtools.build.java.turbine.javac.JavacTurbineCompileResult.Status; -import com.google.devtools.build.java.turbine.javac.ZipOutputFileManager.OutputFileObject; import com.sun.source.util.JavacTask; import com.sun.tools.javac.api.JavacTool; import com.sun.tools.javac.file.CacheFSInfo; +import com.sun.tools.javac.file.JavacFileManager; import com.sun.tools.javac.util.Context; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; +import java.nio.file.FileSystem; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; @@ -38,7 +47,7 @@ public class JavacTurbineCompiler { static JavacTurbineCompileResult compile(JavacTurbineCompileRequest request) throws IOException { - Map<String, OutputFileObject> files = new LinkedHashMap<>(); + Map<String, byte[]> files = new LinkedHashMap<>(); Status status; StringWriter sw = new StringWriter(); Context context = new Context(); @@ -46,7 +55,8 @@ public class JavacTurbineCompiler { try (PrintWriter pw = new PrintWriter(sw)) { setupContext(context, request.strictJavaDepsPlugin()); CacheFSInfo.preRegister(context); - try (ZipOutputFileManager fm = new ZipOutputFileManager(files)) { + try (FileSystem fs = Jimfs.newFileSystem(Configuration.forCurrentPlatform()); + JavacFileManager fm = new JavacFileManager(new Context(), false, UTF_8)) { JavacTask task = JavacTool.create() .getTask( @@ -58,14 +68,34 @@ public class JavacTurbineCompiler { fm.getJavaFileObjectsFromPaths(request.sources()), context); + Path classes = fs.getPath("/classes"); + Files.createDirectories(classes); + Path sources = fs.getPath("/sources"); + Files.createDirectories(sources); + fm.setContext(context); fm.setLocationFromPaths(StandardLocation.SOURCE_PATH, Collections.<Path>emptyList()); fm.setLocationFromPaths(StandardLocation.CLASS_PATH, request.classPath()); fm.setLocationFromPaths(StandardLocation.PLATFORM_CLASS_PATH, request.bootClassPath()); fm.setLocationFromPaths( StandardLocation.ANNOTATION_PROCESSOR_PATH, request.processorClassPath()); + fm.setLocationFromPaths(StandardLocation.CLASS_OUTPUT, ImmutableList.of(classes)); + fm.setLocationFromPaths(StandardLocation.SOURCE_OUTPUT, ImmutableList.of(sources)); status = task.call() ? Status.OK : Status.ERROR; + + // collect class output + Files.walkFileTree( + classes, + new SimpleFileVisitor<Path>() { + @Override + public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) + throws IOException { + files.put(classes.relativize(path).toString(), Files.readAllBytes(path)); + return FileVisitResult.CONTINUE; + } + }); + } catch (Throwable t) { t.printStackTrace(pw); status = Status.ERROR; diff --git a/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbineJavaCompiler.java b/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbineJavaCompiler.java index b17cde85bd..4f38892349 100644 --- a/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbineJavaCompiler.java +++ b/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbineJavaCompiler.java @@ -40,7 +40,6 @@ class JavacTurbineJavaCompiler extends JavaCompiler implements AutoCloseable { public JavacTurbineJavaCompiler(Context context, @Nullable StrictJavaDepsPlugin strictJavaDeps) { super(context); this.strictJavaDeps = strictJavaDeps; - JavaCompiler comp = JavaCompiler.instance(context); if (strictJavaDeps != null) { strictJavaDeps.init(context, Log.instance(context), this); } diff --git a/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/ZipOutputFileManager.java b/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/ZipOutputFileManager.java deleted file mode 100644 index 7bbe35b086..0000000000 --- a/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/ZipOutputFileManager.java +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright 2016 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.java.turbine.javac; - -import com.sun.tools.javac.api.ClientCodeWrapper.Trusted; -import com.sun.tools.javac.file.JavacFileManager; -import com.sun.tools.javac.util.Context; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.URI; -import java.net.URL; -import java.net.URLClassLoader; -import java.nio.ByteBuffer; -import java.nio.charset.CharsetDecoder; -import java.nio.charset.CodingErrorAction; -import java.nio.charset.StandardCharsets; -import java.util.Map; -import javax.annotation.Nullable; -import javax.tools.FileObject; -import javax.tools.JavaFileObject; -import javax.tools.SimpleJavaFileObject; -import javax.tools.StandardLocation; - -/** A {@link JavacFileManager} that collects output into a zipfile. */ -@Trusted -public class ZipOutputFileManager extends JavacFileManager { - - private final Map<String, OutputFileObject> files; - - public ZipOutputFileManager(Map<String, OutputFileObject> files) { - super(new Context(), false, StandardCharsets.UTF_8); - this.files = files; - } - - public void setContext(Context context) { - super.setContext(context); - } - - /** - * Returns true if the file manager owns this location; otherwise it delegates to the underlying - * implementation. - */ - private boolean ownedLocation(Location location) { - return location.isOutputLocation() && location != StandardLocation.NATIVE_HEADER_OUTPUT; - } - - @Override - public boolean hasLocation(Location location) { - return ownedLocation(location) || super.hasLocation(location); - } - - private OutputFileObject getOutput(String name, JavaFileObject.Kind kind, Location location) { - if (files.containsKey(name)) { - return files.get(name); - } - OutputFileObject result = new OutputFileObject(name, kind, location); - files.put(name, result); - return result; - } - - @Override - public JavaFileObject getJavaFileForOutput( - Location location, String className, JavaFileObject.Kind kind, FileObject sibling) - throws IOException { - if (!ownedLocation(location)) { - return super.getJavaFileForOutput(location, className, kind, sibling); - } - // The classname parameter will be something like - // "java.util.Map$Entry"; nested classes are delimited with - // dollar signs, so the following transformation works as intended. - return getOutput(className.replace('.', '/') + kind.extension, kind, location); - } - - @Override - public FileObject getFileForOutput( - Location location, String packageName, String relativeName, FileObject sibling) - throws IOException { - if (!ownedLocation(location)) { - return super.getFileForOutput(location, packageName, relativeName, sibling); - } - String path = ""; - if (packageName != null && !packageName.isEmpty()) { - path = packageName.replace('.', '/') + '/'; - } - path += relativeName; - return getOutput(path, JavaFileObject.Kind.OTHER, location); - } - - @Override - public boolean isSameFile(FileObject a, FileObject b) { - boolean at = a instanceof OutputFileObject; - boolean bt = b instanceof OutputFileObject; - if (at || bt) { - if (at ^ bt) { - return false; - } - return ((OutputFileObject) a).toUri().equals(((OutputFileObject) b).toUri()); - } - return super.isSameFile(a, b); - } - - /** A {@link JavaFileObject} that accumulates output in memory. */ - public static class OutputFileObject extends SimpleJavaFileObject { - - public final Location location; - - @Nullable private ByteArrayOutputStream buffer; - - public OutputFileObject(String name, Kind kind, Location location) { - super(URI.create("outputbuffer:/" + name), kind); - this.location = location; - } - - @Override - public OutputStream openOutputStream() { - if (buffer == null) { - buffer = new ByteArrayOutputStream(); - } - return buffer; - } - - @Override - public InputStream openInputStream() throws IOException { - if (buffer == null) { - throw new FileNotFoundException(getName()); - } - return new ByteArrayInputStream(asBytes()); - } - - @Override - public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { - if (buffer == null) { - throw new FileNotFoundException(getName()); - } - CodingErrorAction errorAction = - ignoreEncodingErrors ? CodingErrorAction.IGNORE : CodingErrorAction.REPORT; - CharsetDecoder decoder = - StandardCharsets.UTF_8 - .newDecoder() - .onUnmappableCharacter(errorAction) - .onMalformedInput(errorAction); - return decoder.decode(ByteBuffer.wrap(asBytes())); - } - - public byte[] asBytes() { - return buffer != null ? buffer.toByteArray() : null; - } - } - - @Override - protected ClassLoader getClassLoader(URL[] urls) { - // mask turbine classes from the processor classpath to avoid version skew - return new URLClassLoader(urls, null); - } -} diff --git a/src/java_tools/buildjar/javatests/com/google/devtools/build/java/turbine/javac/JavacTurbineTest.java b/src/java_tools/buildjar/javatests/com/google/devtools/build/java/turbine/javac/JavacTurbineTest.java index ab68d1886b..1613cae0b5 100644 --- a/src/java_tools/buildjar/javatests/com/google/devtools/build/java/turbine/javac/JavacTurbineTest.java +++ b/src/java_tools/buildjar/javatests/com/google/devtools/build/java/turbine/javac/JavacTurbineTest.java @@ -825,7 +825,7 @@ public class JavacTurbineTest { new JavacTurbine(new PrintWriter(sw, true), optionsBuilder.build())) { Result result = turbine.compile(); assertThat(result).isEqualTo(Result.ERROR); - assertThat(sw.toString()).contains("error reading"); + assertThat(sw.toString()).contains("unmappable character for encoding UTF-8"); } } @@ -1080,7 +1080,7 @@ public class JavacTurbineTest { new JavacTurbine(new PrintWriter(errOutput, true), optionsBuilder.build())) { assertThat(turbine.compile()).isEqualTo(Result.ERROR); } - assertThat(errOutput.toString()).contains("FileNotFoundException: /NO_SUCH_FILE"); + assertThat(errOutput.toString()).contains("NoSuchFileException: /classes/NO_SUCH_FILE"); } @Test |