Skip to content

Commit

Permalink
Support Bazel reduced classpaths in javac-turbine
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 266801100
  • Loading branch information
cushon authored and copybara-github committed Sep 2, 2019
1 parent 79565c7 commit d190bb1
Show file tree
Hide file tree
Showing 6 changed files with 250 additions and 80 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ java_library(
":zip_util",
"//src/java_tools/buildjar/java/com/google/devtools/build/buildjar:javac_options",
"//src/java_tools/buildjar/java/com/google/devtools/build/buildjar/javac/plugins:dependency",
"//src/main/protobuf:deps_java_proto",
"//third_party:asm",
"//third_party:guava",
"//third_party:jsr305",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@
import com.google.devtools.build.buildjar.javac.JavacOptions.JavacOptionNormalizer;
import com.google.devtools.build.buildjar.javac.plugins.dependency.DependencyModule;
import com.google.devtools.build.buildjar.javac.plugins.dependency.StrictJavaDepsPlugin;
import com.google.devtools.build.lib.view.proto.Deps.Dependencies;
import com.google.turbine.options.TurbineOptions;
import com.google.turbine.options.TurbineOptions.ReducedClasspathMode;
import com.google.turbine.options.TurbineOptionsParser;
import com.sun.tools.javac.util.Context;
import java.io.BufferedOutputStream;
Expand Down Expand Up @@ -135,72 +137,101 @@ Result compile() throws IOException {
}

Result result = Result.ERROR;
JavacTurbineCompileResult compileResult = null;
ImmutableList<Path> actualClasspath = ImmutableList.of();

ImmutableList<Path> originalClasspath = asPaths(turbineOptions.classPath());
ImmutableList<Path> compressedClasspath =
dependencyModule.computeStrictClasspath(originalClasspath);
JavacTurbineCompileResult compileResult;

requestBuilder.setStrictDepsPlugin(new StrictJavaDepsPlugin(dependencyModule));

JavacTransitive transitive = new JavacTransitive(platformJars);
requestBuilder.setTransitivePlugin(transitive);

if (turbineOptions.shouldReduceClassPath()) {
// compile with reduced classpath
actualClasspath = compressedClasspath;
requestBuilder.setClassPath(actualClasspath);
compileResult = JavacTurbineCompiler.compile(requestBuilder.build());
if (compileResult.success()) {
result = Result.OK_WITH_REDUCED_CLASSPATH;
context = compileResult.context();
}
}

if (compileResult == null || shouldFallBack(compileResult)) {
// fall back to transitive classpath
actualClasspath = originalClasspath;
// reset SJD plugin
requestBuilder.setStrictDepsPlugin(new StrictJavaDepsPlugin(dependencyModule));
requestBuilder.setClassPath(actualClasspath);
compileResult = JavacTurbineCompiler.compile(requestBuilder.build());
if (compileResult.success()) {
result = Result.OK_WITH_FULL_CLASSPATH;
context = compileResult.context();
}
ReducedClasspathMode reducedClasspathMode = turbineOptions.reducedClasspathMode();
switch (reducedClasspathMode) {
case BAZEL_FALLBACK:
case NONE:
compileResult =
JavacTurbineCompiler.compile(
requestBuilder.build(), asPaths(turbineOptions.classPath()));
if (compileResult.success()) {
result = Result.OK_WITH_FULL_CLASSPATH;
}
break;
case JAVABUILDER_REDUCED:
// compile with reduced classpath
compileResult =
JavacTurbineCompiler.compile(
requestBuilder.build(),
dependencyModule.computeStrictClasspath(asPaths(turbineOptions.classPath())));
if (compileResult.success()) {
result = Result.OK_WITH_REDUCED_CLASSPATH;
} else if (shouldFallBack(compileResult)) {
// fall back to transitive classpath
printDiagnostics(compileResult);
out.println("warning: falling back to transitive classpath");
// reset SJD plugin
requestBuilder.setStrictDepsPlugin(new StrictJavaDepsPlugin(dependencyModule));
compileResult =
JavacTurbineCompiler.compile(
requestBuilder.build(), asPaths(turbineOptions.classPath()));
if (compileResult.success()) {
result = Result.OK_WITH_FULL_CLASSPATH;
}
}
break;
case BAZEL_REDUCED:
compileResult =
JavacTurbineCompiler.compile(
requestBuilder.build(), asPaths(turbineOptions.classPath()));
if (compileResult.success()) {
result = Result.OK_WITH_REDUCED_CLASSPATH;
} else {
printDiagnostics(compileResult);
out.println("warning: falling back to transitive classpath");
result = Result.REQUIRES_FALLBACK;
}
break;
default:
throw new AssertionError(reducedClasspathMode);
}

context = compileResult.context();
if (result.ok()) {
emitClassJar(
turbineOptions, compileResult.classOutputs(), transitive.collectTransitiveDependencies());
emitGensrcJar(turbineOptions, compileResult.sourceOutputs());
dependencyModule.emitDependencyInformation(
actualClasspath, compileResult.success(), /*requiresFallback=*/ false);
compileResult.classPath(), compileResult.success(), result.requiresFallback());
} else {
for (FormattedDiagnostic diagnostic : compileResult.diagnostics()) {
out.println(diagnostic.message());
}
out.print(compileResult.output());
printDiagnostics(compileResult);
}
return result;
}

private void printDiagnostics(JavacTurbineCompileResult compileResult) {
for (FormattedDiagnostic diagnostic : compileResult.diagnostics()) {
out.println(diagnostic.message());
}
out.print(compileResult.output());
}

/** A header compilation result. */
public enum Result {
/** The compilation succeeded with the reduced classpath optimization. */
OK_WITH_REDUCED_CLASSPATH(true),
OK_WITH_REDUCED_CLASSPATH(/* ok= */ true, /* requiresFallback= */ false),

/** The compilation succeeded, but had to fall back to a transitive classpath. */
OK_WITH_FULL_CLASSPATH(true),
OK_WITH_FULL_CLASSPATH(/* ok= */ true, /* requiresFallback= */ false),

/** The compilation requires bazel transitive classpath fallback. */
REQUIRES_FALLBACK(/* ok= */ true, /* requiresFallback= */ true),

/** The compilation did not succeed. */
ERROR(false);
ERROR(/* ok= */ false, /* requiresFallback= */ false);

private final boolean ok;
private final boolean requiresFallback;

private Result(boolean ok) {
private Result(boolean ok, boolean requiresFallback) {
this.ok = ok;
this.requiresFallback = requiresFallback;
}

public boolean ok() {
Expand All @@ -210,6 +241,10 @@ public boolean ok() {
public int exitCode() {
return ok ? 0 : 1;
}

public boolean requiresFallback() {
return requiresFallback;
}
}

private static final int ZIPFILE_BUFFER_SIZE = 1024 * 16;
Expand Down Expand Up @@ -515,6 +550,22 @@ private static boolean shouldFallBack(JavacTurbineCompileResult result) {
return false;
}

/**
* Writes a jdeps proto that indiciates to Blaze that the transitive classpath compilation failed,
* and it should fall back to the transitive classpath. Used only when {@link
* ReducedClasspathMode#BAZEL_REDUCED}.
*/
public static void writeJdepsForFallback(TurbineOptions options) throws IOException {
try (OutputStream os =
new BufferedOutputStream(Files.newOutputStream(Paths.get(options.outputDeps().get())))) {
Dependencies.newBuilder()
.setRuleLabel(options.targetLabel().get())
.setRequiresReducedClasspathFallback(true)
.build()
.writeTo(os);
}
}

@Override
public void close() throws IOException {
out.flush();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
class JavacTurbineCompileRequest {

private final ImmutableList<Path> sources;
private final ImmutableList<Path> classPath;
private final ImmutableList<Path> bootClassPath;
private final ImmutableSet<String> builtinProcessors;
private final ImmutableList<Path> processorClassPath;
Expand All @@ -36,15 +35,13 @@ class JavacTurbineCompileRequest {

JavacTurbineCompileRequest(
ImmutableList<Path> sources,
ImmutableList<Path> classPath,
ImmutableList<Path> bootClassPath,
ImmutableSet<String> builtinProcessors,
ImmutableList<Path> processorClassPath,
ImmutableList<String> javacOptions,
@Nullable StrictJavaDepsPlugin strictJavaDepsPlugin,
JavacTransitive transitivePlugin) {
this.sources = checkNotNull(sources);
this.classPath = checkNotNull(classPath);
this.bootClassPath = checkNotNull(bootClassPath);
this.builtinProcessors = checkNotNull(builtinProcessors);
this.processorClassPath = checkNotNull(processorClassPath);
Expand All @@ -58,11 +55,6 @@ ImmutableList<Path> sources() {
return sources;
}

/** The class path; correspond's to javac -classpath. */
ImmutableList<Path> classPath() {
return classPath;
}

/** The boot class path; corresponds to javac -bootclasspath. */
ImmutableList<Path> bootClassPath() {
return bootClassPath;
Expand Down Expand Up @@ -100,7 +92,6 @@ static JavacTurbineCompileRequest.Builder builder() {

static class Builder {
private ImmutableList<Path> sources;
private ImmutableList<Path> classPath;
private ImmutableList<Path> bootClassPath;
private ImmutableSet<String> builtinProcessors;
private ImmutableList<Path> processorClassPath;
Expand All @@ -113,7 +104,6 @@ private Builder() {}
JavacTurbineCompileRequest build() {
return new JavacTurbineCompileRequest(
sources,
classPath,
bootClassPath,
builtinProcessors,
processorClassPath,
Expand All @@ -127,11 +117,6 @@ Builder setSources(ImmutableList<Path> sources) {
return this;
}

Builder setClassPath(ImmutableList<Path> classPath) {
this.classPath = classPath;
return this;
}

Builder setBootClassPath(ImmutableList<Path> bootClassPath) {
this.bootClassPath = bootClassPath;
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.sun.tools.javac.util.Context;
import java.nio.file.Path;

/** The output from a {@link JavacTurbineCompiler} compilation. */
class JavacTurbineCompileResult {
Expand All @@ -30,6 +31,7 @@ enum Status {
private final ImmutableMap<String, byte[]> classOutputs;
private final ImmutableMap<String, byte[]> sourceOutputs;
private final Status status;
private final ImmutableList<Path> classPath;
private final String output;
private final ImmutableList<FormattedDiagnostic> diagnostics;
private final Context context;
Expand All @@ -38,12 +40,14 @@ enum Status {
ImmutableMap<String, byte[]> classOutputs,
ImmutableMap<String, byte[]> sourceOutputs,
Status status,
ImmutableList<Path> classPath,
String output,
ImmutableList<FormattedDiagnostic> diagnostics,
Context context) {
this.classOutputs = classOutputs;
this.sourceOutputs = sourceOutputs;
this.status = status;
this.classPath = classPath;
this.output = output;
this.diagnostics = diagnostics;
this.context = context;
Expand All @@ -54,6 +58,11 @@ boolean success() {
return status == Status.OK;
}

/** The classpath used for the compilation. */
public ImmutableList<Path> classPath() {
return classPath;
}

/** The stderr from the compilation. */
String output() {
return output;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@
/** Performs a javac-based turbine compilation given a {@link JavacTurbineCompileRequest}. */
public class JavacTurbineCompiler {

static JavacTurbineCompileResult compile(JavacTurbineCompileRequest request) throws IOException {
static JavacTurbineCompileResult compile(
JavacTurbineCompileRequest request, ImmutableList<Path> classPath) throws IOException {

Map<String, byte[]> classOutputs = new LinkedHashMap<>();
Map<String, byte[]> sourceOutputs = new LinkedHashMap<>();
Expand Down Expand Up @@ -87,7 +88,7 @@ static JavacTurbineCompileResult compile(JavacTurbineCompileRequest request) thr

fm.setContext(context);
fm.setLocationFromPaths(StandardLocation.SOURCE_PATH, Collections.<Path>emptyList());
fm.setLocationFromPaths(StandardLocation.CLASS_PATH, request.classPath());
fm.setLocationFromPaths(StandardLocation.CLASS_PATH, classPath);
// The bootclasspath may legitimately be empty if --release is being used.
Collection<Path> bootClassPath = request.bootClassPath();
if (!bootClassPath.isEmpty()) {
Expand All @@ -114,6 +115,7 @@ static JavacTurbineCompileResult compile(JavacTurbineCompileRequest request) thr
ImmutableMap.copyOf(classOutputs),
ImmutableMap.copyOf(sourceOutputs),
status,
classPath,
sw.toString(),
diagnostics.build(),
context);
Expand Down
Loading

0 comments on commit d190bb1

Please sign in to comment.