I am running into various problems when trying to run android start-server
from within Java as external process. The Java is called by Gradle. Let me describe to you what is exactly happening in various scenarios:
Environment
- Windows 7 X64
- Java 7
- commons-exec-1.1
- Gradle 1.6
- Android API 17
- IntelliJ IDEA 12.1.4 Community Edition
Assumption
adb daemon is killed and will start up when calling adb start-server
.
Case 1
This code:
DefaultExecutor executor = new org.apache.commons.exec.DefaultExecutor();
executor.execute(org.apache.commons.exec.CommandLine.parse("adb start-server"));
log.info("Checkpoint!");
When run from Gradle run
task of the application plugin, will display the start-server output, i.e.:
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
and then it will hang, i.e. "Checkpoint!" will never be logged. Killing the adb.exe
process manually will cause the code to continue execution.
Question 1
Why this call blocks? When adb start-server
command is run from terminal, after a couple of seconds the control is returned to the terminal, so why it doesn't happen in the code?
Case 2
If instead I use directly the Java runtime like so:
Runtime.getRuntime().exec(new String[]{"adb", "start-server"});
log.info("Checkpoint!");
System.exit(0);
If calling from Gradle as previously, the "Checkpoint!" will be logged. However, the execution will hang on System.exit(0)
. Killing adb.exe
manually will again make Gradle call finish.
In this case no output of adb start-server
is displayed.
Interesting thing is that when, instead of Gradle, I run the application from IntelliJ IDEA with build setup mimicking that of Gradle's, everything works fine and the application finishes properly.
Question 2
Why Gradle hangs on System.exit(0)
and IntelliJ doesn't? Is this somehow related to the fact that Gradle itself is a process that internally calls Java and in case of IntelliJ, Java is called immediately without any indirection? Why does it matter?
Question 3
Ultimately, I want to be able to run this from Gradle without hangs of any kind. Logging output of adb start-server
would be a bonus. I would greatly appreciate any hints how to do this.