diff --git a/src/tools/android/java/com/google/devtools/build/android/ResourceProcessorBusyBox.java b/src/tools/android/java/com/google/devtools/build/android/ResourceProcessorBusyBox.java index 084c028ed866f8..b92297e44e8705 100644 --- a/src/tools/android/java/com/google/devtools/build/android/ResourceProcessorBusyBox.java +++ b/src/tools/android/java/com/google/devtools/build/android/ResourceProcessorBusyBox.java @@ -27,7 +27,11 @@ import com.google.devtools.common.options.OptionsParsingException; import com.google.devtools.common.options.ShellQuotedParamsFilePreProcessor; -import java.io.*; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintStream; +import java.io.PrintWriter; import java.nio.file.FileSystems; import java.time.Duration; import java.util.Arrays; @@ -140,6 +144,8 @@ void call(String[] args) throws Exception { private static final Logger logger = Logger.getLogger(ResourceProcessorBusyBox.class.getName()); private static final Properties properties = loadSiteCustomizations(); + // Static object locked used when reading/resetting the shared byte buffer + private static final Object LOCK = new Object(); /** Converter for the Tool enum. */ public static final class ToolConverter extends EnumConverter { @@ -220,11 +226,14 @@ private static int processRequest(List args, PrintWriter pw, ByteArrayOu e.printStackTrace(pw); exitCode = 1; } finally { - // Write the captured buffer to the work response - String captured = buf.toString().trim(); - buf.reset(); - if (!captured.isEmpty()) { - pw.print(captured); + // Write the captured buffer to the work response. We synchronize to avoid race conditions + // while reading from and calling reset on the shared ByteArrayOutputStream. + synchronized (LOCK) { + String captured = buf.toString().trim(); + buf.reset(); + if (!captured.isEmpty()) { + pw.print(captured); + } } }