diff options
author | Yuan Liao <liaoyuan@gmail.com> | 2021-06-14 09:09:15 -0700 |
---|---|---|
committer | Miroslav Šulc <fordfrog@gentoo.org> | 2021-06-15 09:40:21 +0200 |
commit | 61ac9154ef648de0dacbc8f1977d093c1374cca4 (patch) | |
tree | 74ae782c651d7201ace26da12cc2ab2f39484196 /src | |
parent | put unzip in BDEPEND (diff) | |
download | java-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>
Diffstat (limited to 'src')
-rw-r--r-- | src/main/java/org/gentoo/java/ebuilder/maven/MavenParser.java | 4 |
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", |