blob: c15f49a723ee993c94170a05d3522e44d20bd611 [file] [log] [blame]
// Copyright 2007 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.JavacOptions;
import com.google.devtools.build.buildjar.javac.plugins.BlazeJavaCompilerPlugin;
import com.google.devtools.build.buildjar.javac.plugins.classloader.ClassLoaderMaskingPlugin;
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.WorkerProtocol.WorkRequest;
import com.google.devtools.build.lib.worker.WorkerProtocol.WorkResponse;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.List;
import java.util.ListIterator;
/**
* The JavaBuilder main called by bazel.
*/
public abstract class BazelJavaBuilder {
private static final String CMDNAME = "BazelJavaBuilder";
/**
* The main method of the BazelJavaBuilder.
*/
public static void main(String[] args) {
if (args.length == 1 && args[0].equals("--persistent_worker")) {
System.exit(runPersistentWorker());
} else {
// This is a single invocation of JavaBuilder that exits after it processed the request.
int exitCode = 1;
try (PrintWriter err =
new PrintWriter(new OutputStreamWriter(System.err, Charset.defaultCharset()))) {
exitCode = processRequest(Arrays.asList(args), err);
}
System.exit(exitCode);
}
}
private static int runPersistentWorker() {
while (true) {
try {
WorkRequest request = WorkRequest.parseDelimitedFrom(System.in);
if (request == null) {
break;
}
try (StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw)) {
int exitCode = processRequest(request.getArgumentsList(), pw);
WorkResponse.newBuilder()
.setOutput(sw.toString())
.setExitCode(exitCode)
.build()
.writeDelimitedTo(System.out);
System.out.flush();
}
} catch (IOException e) {
e.printStackTrace();
return 1;
}
}
return 0;
}
public static int processRequest(List<String> args, PrintWriter err) {
try {
JavaLibraryBuildRequest build = parse(args);
AbstractJavaBuilder builder = build.getDependencyModule().reduceClasspath()
? new ReducedClasspathJavaLibraryBuilder()
: new SimpleJavaLibraryBuilder();
return builder.run(build, err).exitCode;
} catch (InvalidCommandLineException e) {
System.err.println(CMDNAME + " threw exception: " + e.getMessage());
return 1;
} catch (Exception e) {
e.printStackTrace();
return 1;
}
}
private static boolean processAndRemoveExtraChecksOptions(List<String> args) {
// error-prone is enabled by default for Bazel.
boolean errorProneEnabled = true;
ListIterator<String> arg = args.listIterator();
while (arg.hasNext()) {
switch (arg.next()) {
case "-extra_checks":
case "-extra_checks:on":
errorProneEnabled = true;
arg.remove();
break;
case "-extra_checks:off":
errorProneEnabled = false;
arg.remove();
break;
}
}
return errorProneEnabled;
}
/**
* 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 static JavaLibraryBuildRequest parse(List<String> args) throws IOException,
InvalidCommandLineException {
OptionsParser optionsParser = new OptionsParser(args);
ImmutableList.Builder<BlazeJavaCompilerPlugin> plugins = ImmutableList.builder();
plugins.add(new ClassLoaderMaskingPlugin());
// Support for -extra_checks:off was removed from ErrorPronePlugin, but Bazel still needs it,
// so we'll emulate support for this here by handling the flag ourselves and not loading the
// plug-in when it is specified.
boolean errorProneEnabled = processAndRemoveExtraChecksOptions(optionsParser.getJavacOpts());
if (errorProneEnabled) {
plugins.add(new ErrorPronePlugin());
}
JavaLibraryBuildRequest build =
new JavaLibraryBuildRequest(optionsParser, plugins.build(), new DependencyModule.Builder());
build.setJavacOpts(JavacOptions.normalizeOptions(build.getJavacOpts()));
return build;
}
}