blob: 62e01a5e829c682483d1ab9b6eaf223a223baa24 [file] [log] [blame]
// 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.buildjar;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.buildjar.javac.BlazeJavacResult;
import com.google.devtools.build.buildjar.javac.BlazeJavacResult.Status;
import com.google.devtools.build.buildjar.javac.FormattedDiagnostic;
import com.google.devtools.build.buildjar.javac.JavacOptions;
import com.google.devtools.build.buildjar.javac.plugins.BlazeJavaCompilerPlugin;
import com.google.devtools.build.buildjar.javac.plugins.dependency.DependencyModule;
import com.google.devtools.build.buildjar.javac.plugins.errorprone.ErrorPronePlugin;
import com.google.devtools.build.lib.worker.ProtoWorkerMessageProcessor;
import com.google.devtools.build.lib.worker.WorkRequestHandler;
import com.google.devtools.build.lib.worker.WorkRequestHandler.WorkRequestHandlerBuilder;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.time.Duration;
import java.util.Arrays;
import java.util.List;
/** The JavaBuilder main called by bazel. */
public class BazelJavaBuilder {
private static final String CMDNAME = "BazelJavaBuilder";
/** The main method of the BazelJavaBuilder. */
public static void main(String[] args) {
BazelJavaBuilder builder = new BazelJavaBuilder();
if (args.length == 1 && args[0].equals("--persistent_worker")) {
WorkRequestHandler workerHandler =
new WorkRequestHandlerBuilder(
new WorkRequestHandler.WorkRequestCallback(
(workRequest, printWriter) ->
builder.parseAndBuild(
workRequest.getArgumentsList(),
Path.of(workRequest.getSandboxDir()),
printWriter)),
System.err,
new ProtoWorkerMessageProcessor(System.in, System.out))
.setCpuUsageBeforeGc(Duration.ofSeconds(10))
.build();
int exitCode = 1;
try {
workerHandler.processRequests();
exitCode = 0;
} catch (IOException e) {
System.err.println(e.getMessage());
} finally {
// Prevent hanging threads from keeping the worker alive.
System.exit(exitCode);
}
} else {
PrintWriter pw =
new PrintWriter(new OutputStreamWriter(System.err, Charset.defaultCharset()));
int returnCode;
try {
returnCode = builder.parseAndBuild(Arrays.asList(args), Path.of(""), pw);
} finally {
pw.flush();
}
System.exit(returnCode);
}
}
public int parseAndBuild(List<String> args, Path workDir, PrintWriter pw) {
try {
JavaLibraryBuildRequest build = parse(args, workDir);
try (SimpleJavaLibraryBuilder builder =
build.getDependencyModule().reduceClasspath()
? new ReducedClasspathJavaLibraryBuilder()
: new SimpleJavaLibraryBuilder()) {
return build(builder, build, pw);
}
} catch (InvalidCommandLineException e) {
pw.println(CMDNAME + " threw exception: " + e.getMessage());
return 1;
} catch (Exception e) {
e.printStackTrace();
return 1;
}
}
/**
* Uses {@code builder} to build the target passed in {@code buildRequest}. All errors and
* diagnostics should be written to {@code err}.
*
* @return An error code, 0 is success, any other value is an error.
*/
protected int build(
SimpleJavaLibraryBuilder builder, JavaLibraryBuildRequest buildRequest, Writer err)
throws Exception {
BlazeJavacResult result = builder.run(buildRequest);
if (result.status() == Status.REQUIRES_FALLBACK) {
return 0;
}
for (FormattedDiagnostic d : result.diagnostics()) {
err.write(d.getFormatted() + "\n");
}
err.write(result.output());
return result.isOk() ? 0 : 1;
}
/**
* Parses the list of arguments into a {@link JavaLibraryBuildRequest}. The returned {@link
* JavaLibraryBuildRequest} object can be then used to configure the compilation itself.
*
* @throws IOException if the argument list contains a file (with the @ prefix) and reading that
* file failed
* @throws InvalidCommandLineException on any command line error
*/
@VisibleForTesting
public JavaLibraryBuildRequest parse(List<String> args, Path workDir)
throws IOException, InvalidCommandLineException {
OptionsParser optionsParser =
new OptionsParser(args, JavacOptions.createWithWarningsAsErrorsDefault(ImmutableList.of()));
ImmutableList<BlazeJavaCompilerPlugin> plugins =
ImmutableList.of(new ErrorPronePlugin(BazelScannerSuppliers.bazelChecks()));
return new JavaLibraryBuildRequest(
optionsParser, plugins, new DependencyModule.Builder(), workDir);
}
}