JAVA_HOME is not set
dwb357 opened this issue · comments
Looking for a reliable way to start android emulators for CI testing and stumbled across this. Unfortunately, it doesn't seem to be working in my environment. I get the following error sequence (on a formerly working project), even if I explicitly define JAVA_HOME and java is in /usr/bin/java, on all the default paths on a Mac.
> Task :ui-android:installAndroidEmulatorSystemImage
ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation.
> Task :ui-android:installAndroidEmulatorSystemImage FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':ui-android:installAndroidEmulatorSystemImage'.
> Process 'command '/Users/dberry/Library/Android/sdk/tools/bin/sdkmanager'' finished with non-zero exit value 1
If possible, could you link me to your project or ideally the branch that doesn't work so I can play with it to help me debug?
There are a few things I'd like to confirm as part of this investigation
Does running the :ui-android:installAndroidEmulator
task also fail? I expect it would, but if it doesn't that would be interesting.
You said
I get the following error sequence (on a formerly working project), even if I explicitly define JAVA_HOME and java is in /usr/bin/java
By that do you mean you set it on your path explicitly when running gradle?
$ JAVA_HOME=/usr/bin/java ./gradlew 'ui-android:installAndroidEmulatorSystemImage'
These tasks are simply Gradle ExecTask
s so you should be able to set the environment variables of the exec tasks when you run explicitly by adding some code like the following in your build.gradle
file. This should enforce that the JAVA_HOME
that you want is made available when running sdkmanager
. Can you try this and let me know if that works for you?
project.afterEvaluate {
tasks['installAndroidEmulatorSystemImage'].environment('JAVA_HOME', '/usr/bin/java')
}
Does running the :ui-android:installAndroidEmulator task also fail? I expect it would, but if it doesn't that would be interesting.
This also fails.
By that do you mean you set it on your path explicitly when running gradle?
$ JAVA_HOME=/usr/bin/java ./gradlew 'ui-android:installAndroidEmulatorSystemImage'
I use tcsh, but yes, the moral equivalent thereof.
Can you try this and let me know if that works for you?
project.afterEvaluate {
tasks['installAndroidEmulatorSystemImage'].environment('JAVA_HOME', '/usr/bin/java')
}
Doesn't seem to change anything.
If possible, could you link me to your project or ideally the branch that doesn't work so I can play with it to help me debug?
Unfortunately, that's really not an option. I'll see if I can create a minimum reproducible failure though.
Here's a pretty minimal reproducible failure, but it's really pretty much just an empty AAR project.
I will definitely try to take a look at this and reproduce your error this weekend.
Hmm, this is interesting. I've downloaded and built your example and it builds just fine. It installs the android emulator and runs to the point of failing due to there being no tests so my environment doesn't have that issue. I develop on Ubuntu and don't have access to play with a mac setup to reproduce your problem.
Could you try building with Gradle's --debug
flag to see if we can get any other clues as to why java
isn't available when running sdkmanager
?
Here ya go.
I am genuinely perplexed by the differences. Comparing your output vs my own it seems like gradle is reporting the same types out output aside from being unable to run successfully. Unfortunately I'm out of ideas. Do you have access to a linux machine you could try running on and see if it works there? My only guess is that your java environment setup is causing issues due to being configured differently to mine. Is there anything non-standard with your setup or the way you invoke gradle?
Nope. It's a pretty much vanilla Mac install, particularly as far as the java and android installs are concerned.
Hi @quittle and @dwb357,
I see two problems here:
- Plugin reports a problem with incorrect
JAVA_HOME
set even though the real problem is in executingsdkmanager
oravdmanager
command - I've come accros the same problem with calling
sdkmanager
as @dwb357. On macOS the system image arguments need to be in quotes:
./sdkmanager system-images;android-28;default;x86
Warning: Failed to find package system-images
./sdkmanager "system-images;android-28;default;x86"
Runs OK!!!
The same applies when calling avdmanager
.
Not sure how force the quotes when running Exec
Gradle tasks.
@quittle Do you have any idea? And a Mac to test this?
Hey @xsveda, thanks for reaching out.
- The JAVA_HOME is indeed coming from
sdkmanager
. The wrapper script ($SDK_ROOT/tools/bin/sdkmanager
) is just a shell script that does validation before runningjava
on the SDK manager jar in$SDK_ROOT/tools/lib
. During the validation, it appears to detect thatJAVA_HOME
is not set. Here is the point that I believe is displaying the output. See the last clause for the error you are seeing.
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
- In the context of Gradle, you don't need to quote the argument as it is not be executed from the command line. In a terminal, the shell will treat the argument as 4 different statements:
./sdkmanager system-images;android-28;default;x86
->./sdkmanager system-images
,android-28
,default
, andx86
. This is because;
in most shells indicates the end of a statement, so it only seessystem-images
as the argument, not the whole thing. In my plugin, I pass it as the only argument in the list of arguments, so I don't need to escape or otherwise handle the;
or any other character for that matter.
As far as reproducing it myself, unfortunately I don't have a Mac, just Windows and Ubuntu.
Hi @quittle, finally I've found a root cause.
The problem lays here AndroidEmulatorPlugin.java#L190:
task.setEnvironment(emulatorConfiguration.getEnvironmentVariableMap());
setEnvironment(Map)
will replace all system ENV variables with only those in the map (ANDROID_SDK_ROOT
and ANDROID_AVD_HOME
in this case). The required JAVA_HOME
is missing.
To fix it use a different API method environment(Map)
that just adds new ENV variables to the original ones.
task.environment(emulatorConfiguration.getEnvironmentVariableMap());
Do you want me to create a PR?
Yeah, that would be great. Thank you for getting back to me on this issue.
This will be released under version 0.0.2
pending this build: https://travis-ci.com/quittle/gradle-android-emulator/builds/116168104
0.0.2
has been released. Can you try it out and confirm it works for you if you are using the plugin?
@quittle Works!