aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuan Liao <liaoyuan@gmail.com>2021-06-14 09:09:15 -0700
committerMiroslav Šulc <fordfrog@gentoo.org>2021-06-15 09:40:21 +0200
commit61ac9154ef648de0dacbc8f1977d093c1374cca4 (patch)
tree74ae782c651d7201ace26da12cc2ab2f39484196
parentput unzip in BDEPEND (diff)
downloadjava-ebuilder-61ac9154ef648de0dacbc8f1977d093c1374cca4.tar.gz
java-ebuilder-61ac9154ef648de0dacbc8f1977d093c1374cca4.tar.bz2
java-ebuilder-61ac9154ef648de0dacbc8f1977d093c1374cca4.zip
Fix hanging Maven process when lots of artifacts are being downloaded
The MavenParser class uses Java's ProcessBuilder to start a Maven process without consuming the process's output. This might cause the Maven process to hang indefinitely after the output stream buffer is full, because the process is blocked to wait for the contents in the buffer to be cleared, but no other program is going to clear them. When java-ebuilder is asked to create an ebuild for a Maven artifact whose dependencies are mostly not cached in the local Maven repository (stored in ~/.m2 by default), it will call Maven, which in turn will download artifacts for all those dependencies, flooding lots of contents into the output stream. The size of output stream buffers Java uses for the processes created from ProcessBuilder is just 8192 bytes, so with lots of output, the buffer can become full fairly easily. This explains why a hanging process is often observed when java-ebuilder is requested to generate ebuilds for some new Maven artifacts, but interrupting the process and restarting java-ebuilder can resolve the issue. When java-ebuilder is restarted, as long as MAVEN_ARTS is unchanged, it can skip downloading the dependencies that have already been cached in the previous execution before the buffer is full, so the number of artifacts it still needs to download is reduced, and it might be able to complete before the buffer is full again. The solution to this issue is simple: either suppress Maven's output, or consume the output stream buffer's contents to prevent blocking. The former solution is probably more preferable because it only requires minimal change to both the source code and the program's behavior, and it avoids output redirection, which is not easily portable between different operating systems. Reference: https://stackoverflow.com/questions/3285408/java-processbuilder-resultant-process-hangs Signed-off-by: Yuan Liao <liaoyuan@gmail.com> Closes: https://github.com/gentoo/java-ebuilder/pull/10 Signed-off-by: Miroslav Šulc <fordfrog@gentoo.org>
-rw-r--r--src/main/java/org/gentoo/java/ebuilder/maven/MavenParser.java4
1 files changed, 4 insertions, 0 deletions
diff --git a/src/main/java/org/gentoo/java/ebuilder/maven/MavenParser.java b/src/main/java/org/gentoo/java/ebuilder/maven/MavenParser.java
index 07ae96e..1411307 100644
--- a/src/main/java/org/gentoo/java/ebuilder/maven/MavenParser.java
+++ b/src/main/java/org/gentoo/java/ebuilder/maven/MavenParser.java
@@ -110,6 +110,10 @@ public class MavenParser {
final ProcessBuilder processBuilder = new ProcessBuilder("mvn", "-f",
pomFile.toString(), "help:effective-pom",
+ // If output was not suppressed, mvn would hang indefinitely
+ // if new artifact should be downloaded, probably because of
+ // limited output stream buffer size
+ "-q",
"-Doutput=" + outputPath);
processBuilder.directory(config.getWorkdir().toFile());
final ProcessBuilder xmlBuilder = new ProcessBuilder("simple-xml-formatter",