diff options
author | cushon <cushon@google.com> | 2018-04-13 11:57:19 -0700 |
---|---|---|
committer | Copybara-Service <copybara-piper@google.com> | 2018-04-13 11:58:37 -0700 |
commit | b985f619755864acd1a6bde13372c808ac609d35 (patch) | |
tree | 3a2050b12d1c4ce12800a6084c58c6b4b90417bd /src/java_tools/buildjar | |
parent | 7bcdceb2b6593bb2f9ad491433534fedb1188b23 (diff) |
Use jadep to fix missing dependencies in turbine
PiperOrigin-RevId: 192802011
Diffstat (limited to 'src/java_tools/buildjar')
5 files changed, 228 insertions, 103 deletions
diff --git a/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/BUILD b/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/BUILD index f3cafee714..cbade56570 100644 --- a/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/BUILD +++ b/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/BUILD @@ -16,6 +16,7 @@ java_library( deps = [ "//src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac:javac_turbine", "//third_party:guava", + "//third_party:jsr305", "//third_party:turbine", ], ) diff --git a/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/Turbine.java b/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/Turbine.java index b76f18982a..ddf5887de3 100644 --- a/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/Turbine.java +++ b/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/Turbine.java @@ -14,6 +14,10 @@ package com.google.devtools.build.java.turbine; +import static com.google.common.collect.Iterables.getOnlyElement; +import static java.nio.charset.StandardCharsets.UTF_8; + +import com.google.common.base.CharMatcher; import com.google.common.collect.ImmutableList; import com.google.devtools.build.java.turbine.javac.JavacTurbine; import com.google.devtools.build.java.turbine.javac.JavacTurbine.Result; @@ -21,7 +25,11 @@ import com.google.turbine.diag.TurbineError; import com.google.turbine.main.Main; import com.google.turbine.options.TurbineOptions; import com.google.turbine.options.TurbineOptionsParser; +import java.io.BufferedWriter; import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import javax.annotation.Nullable; /** * A turbine entry point that falls back to javac-turbine for failures, and for compilations that @@ -30,23 +38,29 @@ import java.io.IOException; public class Turbine { public static void main(String[] args) throws Exception { - System.exit(new Turbine("An exception has occurred in turbine.", "").compile(args)); + System.exit( + new Turbine("An exception has occurred in turbine.", "", "") + .compile(TurbineOptionsParser.parse(ImmutableList.copyOf(args)))); } private final String bugMessage; - private final String unhelpfulMessage; + // path to jadep binary, see: https://github.com/bazelbuild/tools_jvm_autodeps + private final @Nullable String jadepPath; - public Turbine(String bugMessage, String unhelpfulMessage) { + public Turbine(String bugMessage, String unhelpfulMessage, @Nullable String jadepPath) { this.bugMessage = bugMessage; this.unhelpfulMessage = unhelpfulMessage; + this.jadepPath = jadepPath; } - public int compile(String[] args) throws IOException { - return compile(TurbineOptionsParser.parse(ImmutableList.copyOf(args))); + public int compile(TurbineOptions options) throws IOException { + return compile( + options, + new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.err, UTF_8)), true)); } - public int compile(TurbineOptions options) throws IOException { + public int compile(TurbineOptions options, PrintWriter out) throws IOException { Throwable turbineCrash = null; try { if (Main.compile(options)) { @@ -56,9 +70,8 @@ public class Turbine { } catch (TurbineError e) { switch (e.kind()) { case TYPE_PARAMETER_QUALIFIER: - System.err.println(e.getMessage()); - System.exit(1); - break; + out.println(e.getMessage()); + return 1; default: turbineCrash = e; break; @@ -68,19 +81,36 @@ public class Turbine { } if (!options.javacFallback()) { if (turbineCrash instanceof TurbineError) { - System.err.println(); - System.err.println(turbineCrash.getMessage()); - System.err.println(unhelpfulMessage); + TurbineError turbineError = (TurbineError) turbineCrash; + out.println(); + out.println(turbineError.getMessage()); + switch (turbineError.kind()) { + case SYMBOL_NOT_FOUND: + if (jadepPath != null && options.targetLabel().isPresent()) { + out.println(); + Object arg = getOnlyElement(turbineError.args()); + out.printf( + "\033[35m\033[1m** Command to add missing dependencies:\033[0m" + + "\n%s -classnames=%s %s", + jadepPath, + CharMatcher.anyOf("$/").replaceFrom(arg.toString(), '.'), + options.targetLabel().get()); + out.println(); + } + break; + default: // fall out + } + out.println(unhelpfulMessage); } else if (turbineCrash != null) { - System.err.println(bugMessage); - turbineCrash.printStackTrace(); + out.println(bugMessage); + turbineCrash.printStackTrace(out); } - System.exit(1); + return 1; } Result result = JavacTurbine.compile(options); if (result == Result.OK_WITH_REDUCED_CLASSPATH && turbineCrash != null) { - System.err.println(bugMessage); - turbineCrash.printStackTrace(); + out.println(bugMessage); + turbineCrash.printStackTrace(out); result = Result.ERROR; } return result.exitCode(); 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 082cc8812c..c71fcd9bc6 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 @@ -78,95 +78,15 @@ public class JavacTurbine implements AutoCloseable { } public static Result compile(TurbineOptions turbineOptions) throws IOException { - try (JavacTurbine turbine = - new JavacTurbine( - new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.err, UTF_8))), - turbineOptions)) { - return turbine.compile(); - } - } - - /** A header compilation result. */ - public enum Result { - /** The compilation succeeded with the reduced classpath optimization. */ - OK_WITH_REDUCED_CLASSPATH(true), - - /** The compilation succeeded, but had to fall back to a transitive classpath. */ - OK_WITH_FULL_CLASSPATH(true), - - /** The compilation did not succeed. */ - ERROR(false); - - private final boolean ok; - - private Result(boolean ok) { - this.ok = ok; - } - - public boolean ok() { - return ok; - } - - public int exitCode() { - return ok ? 0 : 1; - } + return compile( + turbineOptions, + new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.err, UTF_8)), true)); } - private static final int ZIPFILE_BUFFER_SIZE = 1024 * 16; - - - private final PrintWriter out; - private final TurbineOptions turbineOptions; - @VisibleForTesting Context context; - - /** Cache of opened zip filesystems for srcjars. */ - private final Map<Path, FileSystem> filesystems = new HashMap<>(); - - public JavacTurbine(PrintWriter out, TurbineOptions turbineOptions) { - this.out = out; - this.turbineOptions = turbineOptions; - } - - /** Creates the compilation javacopts from {@link TurbineOptions}. */ - @VisibleForTesting - static ImmutableList<String> processJavacopts(TurbineOptions turbineOptions) { - ImmutableList<String> javacopts = - JavacOptions.removeBazelSpecificFlags( - JavacOptions.normalizeOptionsWithNormalizers( - turbineOptions.javacOpts(), new JavacOptions.ReleaseOptionNormalizer())); - - ImmutableList.Builder<String> builder = ImmutableList.builder(); - builder.addAll(javacopts); - - // Disable compilation of implicit source files. - // This is insurance: the sourcepath is empty, so we don't expect implicit sources. - builder.add("-implicit:none"); - - // Disable debug info - builder.add("-g:none"); - - // Enable MethodParameters - builder.add("-parameters"); - - // Compile-time jars always use Java 8 - if (javacopts.contains("--release")) { - // javac doesn't allow mixing -source and --release, so use --release if it's already present - // in javacopts. - builder.add("--release"); - builder.add("8"); - } else { - builder.add("-source"); - builder.add("8"); - builder.add("-target"); - builder.add("8"); - } - - if (!turbineOptions.processors().isEmpty()) { - builder.add("-processor"); - builder.add(Joiner.on(',').join(turbineOptions.processors())); + public static Result compile(TurbineOptions turbineOptions, PrintWriter out) throws IOException { + try (JavacTurbine turbine = new JavacTurbine(out, turbineOptions)) { + return turbine.compile(); } - - return builder.build(); } Result compile() throws IOException { @@ -255,6 +175,88 @@ public class JavacTurbine implements AutoCloseable { return result; } + /** A header compilation result. */ + public enum Result { + /** The compilation succeeded with the reduced classpath optimization. */ + OK_WITH_REDUCED_CLASSPATH(true), + + /** The compilation succeeded, but had to fall back to a transitive classpath. */ + OK_WITH_FULL_CLASSPATH(true), + + /** The compilation did not succeed. */ + ERROR(false); + + private final boolean ok; + + private Result(boolean ok) { + this.ok = ok; + } + + public boolean ok() { + return ok; + } + + public int exitCode() { + return ok ? 0 : 1; + } + } + + private static final int ZIPFILE_BUFFER_SIZE = 1024 * 16; + + private final PrintWriter out; + private final TurbineOptions turbineOptions; + @VisibleForTesting Context context; + + /** Cache of opened zip filesystems for srcjars. */ + private final Map<Path, FileSystem> filesystems = new HashMap<>(); + + public JavacTurbine(PrintWriter out, TurbineOptions turbineOptions) { + this.out = out; + this.turbineOptions = turbineOptions; + } + + /** Creates the compilation javacopts from {@link TurbineOptions}. */ + @VisibleForTesting + static ImmutableList<String> processJavacopts(TurbineOptions turbineOptions) { + ImmutableList<String> javacopts = + JavacOptions.removeBazelSpecificFlags( + JavacOptions.normalizeOptionsWithNormalizers( + turbineOptions.javacOpts(), new JavacOptions.ReleaseOptionNormalizer())); + + ImmutableList.Builder<String> builder = ImmutableList.builder(); + builder.addAll(javacopts); + + // Disable compilation of implicit source files. + // This is insurance: the sourcepath is empty, so we don't expect implicit sources. + builder.add("-implicit:none"); + + // Disable debug info + builder.add("-g:none"); + + // Enable MethodParameters + builder.add("-parameters"); + + // Compile-time jars always use Java 8 + if (javacopts.contains("--release")) { + // javac doesn't allow mixing -source and --release, so use --release if it's already present + // in javacopts. + builder.add("--release"); + builder.add("8"); + } else { + builder.add("-source"); + builder.add("8"); + builder.add("-target"); + builder.add("8"); + } + + if (!turbineOptions.processors().isEmpty()) { + builder.add("-processor"); + builder.add(Joiner.on(',').join(turbineOptions.processors())); + } + + return builder.build(); + } + private static DependencyModule buildDependencyModule( TurbineOptions turbineOptions, StrictJavaDeps strictDepsMode, diff --git a/src/java_tools/buildjar/javatests/com/google/devtools/build/java/turbine/BUILD b/src/java_tools/buildjar/javatests/com/google/devtools/build/java/turbine/BUILD index 73cea18cae..6d36a7392d 100644 --- a/src/java_tools/buildjar/javatests/com/google/devtools/build/java/turbine/BUILD +++ b/src/java_tools/buildjar/javatests/com/google/devtools/build/java/turbine/BUILD @@ -1,5 +1,18 @@ package(default_visibility = ["//src/java_tools/buildjar:buildjar_package_group"]) +java_test( + name = "TurbineTest", + srcs = ["TurbineTest.java"], + deps = [ + "//src/java_tools/buildjar/java/com/google/devtools/build/java/bazel:JavacBootclasspath", + "//src/java_tools/buildjar/java/com/google/devtools/build/java/turbine:turbine_main", + "//third_party:guava", + "//third_party:junit4", + "//third_party:truth", + "//third_party:turbine", + ], +) + filegroup( name = "srcs", srcs = glob(["*.java"]) + [ diff --git a/src/java_tools/buildjar/javatests/com/google/devtools/build/java/turbine/TurbineTest.java b/src/java_tools/buildjar/javatests/com/google/devtools/build/java/turbine/TurbineTest.java new file mode 100644 index 0000000000..465cdcfed7 --- /dev/null +++ b/src/java_tools/buildjar/javatests/com/google/devtools/build/java/turbine/TurbineTest.java @@ -0,0 +1,79 @@ +// Copyright 2018 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; + +import static com.google.common.collect.ImmutableList.toImmutableList; +import static com.google.common.truth.Truth.assertThat; +import static java.nio.charset.StandardCharsets.UTF_8; + +import com.google.common.collect.ImmutableList; +import com.google.devtools.build.java.bazel.JavacBootclasspath; +import com.google.turbine.options.TurbineOptions; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Arrays; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public final class TurbineTest { + + @Rule public final TemporaryFolder tempFolder = new TemporaryFolder(); + + @Test + public void jadepCommand() throws Exception { + + Path source = tempFolder.newFile("Hello.java").toPath(); + Files.write(source, "import p.Lib;\nclass Hello extends Lib {}".getBytes(UTF_8)); + + Path output = tempFolder.newFile("output.jar").toPath(); + Path outputDeps = tempFolder.newFile("output.jdeps").toPath(); + Path tempdir = tempFolder.newFolder("tempdir").toPath(); + + TurbineOptions.Builder optionsBuilder = + TurbineOptions.builder() + .setJavacFallback(false) + .setOutput(output.toString()) + .setTempDir(tempdir.toString()) + .addBootClassPathEntries( + JavacBootclasspath.asPaths() + .stream() + .map(Path::toString) + .collect(toImmutableList())) + .addSources(ImmutableList.of(source.toString())) + .setOutputDeps(outputDeps.toString()) + .addAllJavacOpts(Arrays.asList("-source", "8", "-target", "8")) + .setTargetLabel("//test"); + + StringWriter errOutput = new StringWriter(); + int result = + new Turbine("An exception has occurred in turbine.", "", "jadep") + .compile(optionsBuilder.build(), new PrintWriter(errOutput, true)); + assertThat(errOutput.toString()) + .contains( + "Hello.java:1: error: symbol not found p.Lib\n" + + "import p.Lib;\n" + + " ^\n" + + "\n" + + "\033[35m\033[1m** Command to add missing dependencies:\033[0m\n" + + "jadep -classnames=p.Lib //test"); + assertThat(result).isEqualTo(1); + } +} |