2

I'm fairly new to Docker and am struggling with JAVA_HOME not being seen in a Dockerfile. I get the titular error; which includes Please set the JAVA_HOME variable in your environment to match the location of your Java installation. & executor failed running [/bin/sh -c /opt/Android/cmdline-tools/latest/bin/sdkmanager --update]: exit code: 1 when it runs RUN /opt/Android/cmdline-tools/latest/bin/sdkmanager --update.

I feel like I'm at a loss but I think my issue is not knowing where the JDK is being installed to or knowing how to find it from a Dockerfile; I've tried echoing JAVA_HOME thinking I could see it while the image built but, again, no luck. Any help with this would be greatly appreciated. I've been pulling my hair out Googling & trying things. Thank you.

FROM node:12.12.0

ARG CMDLINE_TOOLS_VERSION=7583922
ARG ANDROID_BUILD_TOOLS=30.0.3

RUN apt-get -qqy update \
    && apt-get -qqy install \
    python-dev \
    --no-install-recommends

RUN apt-get install -y software-properties-common gcc
RUN apt-get update && apt-get install -y  python3-pip
RUN pip3 install awscli
RUN apt-get install -y jq
RUN mkdir -p /usr/share/man/man1 /usr/share/man/man2
RUN apt-get update && apt-get install -y --no-install-recommends openjdk-8-jdk && apt-get clean;

ENV JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
ENV PATH=$PATH:$JAVA_HOME/bin

RUN wget -q https://services.gradle.org/distributions/gradle-4.5.1-bin.zip && unzip gradle-4.5.1-bin.zip -d /opt && rm gradle-4.5.1-bin.zip

ENV GRADLE_HOME=/opt/gradle-4.5.1
ENV PATH=$PATH:/opt/gradle-4.5.1/bin

RUN wget https://dl.google.com/android/repository/commandlinetools-linux-${CMDLINE_TOOLS_VERSION}_latest.zip
RUN mkdir -p /opt/Android/cmdline-tools
RUN  unzip commandlinetools-linux-7583922_latest.zip -d /opt/Android/cmdline-tools
RUN mv /opt/Android/cmdline-tools/cmdline-tools /opt/Android/cmdline-tools/latest

ENV ANDROID_HOME=/opt/Android
ENV PATH="$ANDROID_HOME/emulator:$ANDROID_HOME/tools:$ANDROID_HOME/tools/bin \
:$ANDROID_HOME/cmdline-tools/latest:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$PATH"

RUN /opt/Android/cmdline-tools/latest/bin/sdkmanager --update
RUN /opt/Android/cmdline-tools/latest/bin/sdkmanager --list
RUN /opt/Android/cmdline-tools/latest/bin/sdkmanager --list | grep build-tools
RUN echo y | /opt/Android/cmdline-tools/latest/bin/sdkmanager "build-tools;${ANDROID_BUILD_TOOLS}" "platform-tools" "platforms;android-30" "tools" >/dev/null
RUN yes | /opt/Android/cmdline-tools/latest/bin/sdkmanager --licenses

CMD ["yarn", "start"]
anonymoose
  • 1,169
  • 2
  • 21
  • 62
  • Can you run `RUN ls -lart /usr/lib/jvm/java-8-openjdk-amd64` before running `RUN /opt/Android/cmdline-tools/latest/bin/sdkmanager --update` – harshavmb Oct 25 '22 at 17:35
  • 2
    *ENV PATH=$PATH:$JAVA_HOME/bin* I don't like that. It should be `ENV PATH=$JAVA_HOME/bin:$PATH` You can remove some doubt by running `sudo find / -type f -executable -name java` to find out where each java is – g00se Oct 25 '22 at 17:36
  • @harshavmb, when I run that, I get `cannot access '/usr/lib/jvm/java-8-openjdk-amd64': No such file or directory`, `executor failed running [/bin/sh -c ls -lart /usr/lib/jvm/java-8-openjdk-amd64]: exit code: 2` – anonymoose Oct 25 '22 at 17:50
  • @g00se Thanks; where would I type that, though? – anonymoose Oct 25 '22 at 17:58
  • Sorry I don't do Docker but presumably after a RUN command – g00se Oct 25 '22 at 18:32
  • 2
    I just built a Docker image using your Dockerfile and it went fine. What version of Docker are you using? Can you try to build with `docker build --no-cache .` ? – Pierre B. Oct 28 '22 at 16:38
  • Dont you just have to set the windows or whatever os you are using environment variable to the correct location? Or is this just with docker? Maybe, just missing a `/bin/` on the end of the path you have in the title. You have to point at where the executables are not the root installation folder itself. – invzbl3 Oct 28 '22 at 23:09
  • 1
    *"Maybe, just missing a `/bin/` on the end of the path"* - Wrong! There should NOT be a `/bin/` or `/bin` on the end of `JAVA_HOME`. The convention is that it points to the directory *above* the "bin" directory for the Java install. (And as you can see, the OP does this: `ENV PATH=$PATH:$JAVA_HOME/bin` ...) – Stephen C Oct 31 '22 at 05:13

4 Answers4

3

I'd suggest to use another base image. Java 11 is required to build for newer API levels:

FROM openjdk:11-jdk as builder
...

And then install Python3 and AWS CLI.

Working example: cloudbuild-android.


Or if you want to continue with your's, RUN which java would tell you where it's actually installed.

Martin Zeitler
  • 1
  • 19
  • 155
  • 216
  • 2
    Actually `which java` seldom helps, owing to symlinks. What you want is `readlink -f "$(which java)"` – g00se Oct 31 '22 at 07:27
1

I think your problem is in the line termination characters of your Dockerfile.

Your Dockerfile works in my computer, and when it comes to weird errors, I have been there.

My experience with Dockerfiles is that sometimes they are very picky in the Windows/Unix/Mac line terminators, so please make sure you save the Dockerfile with line terminators adequate for Unix machines.

I have used the method in this other answer to successfully replace Windows line terminators for Unix's on Windows using Powershell. I hope this helps!

The exact location of $JAVA_HOME can be scripted. If you don't feel like hardcoding that directory is a safe bet, replace your ENV line with this RUN: RUN export JAVA_HOME=$(readlink -f $(which java) | sed "s:/bin/java::"). This is how I set up my environment in all my Linux machines, and what it does is the following:

  • which java searches for java and will output /usr/bin/java, or something like that, which is a symbolic link.
  • readlink -f over the above will get you to the destination of the symbolic link.
  • piping such destination over to | sed "s:/bin/java::" will strip the trailing bin/java and get you the right value, no matter the version.

I also tried your Dockerfile with this change, and it does work too.

gvisoc
  • 77
  • 3
  • If this were the case, it would be another error message. Likely already bugging out at the first line. – Martin Zeitler Oct 31 '22 at 04:01
  • No, the error message is accurate when the directory specified doesn't contain a Java installation, and that's usually caused when there is a character in the file garbling the end of the line. As I said, a verbatim copy of the Dockerfile works. Not all lines will necessary fail. – gvisoc Oct 31 '22 at 04:02
  • `/usr/lib/jvm/java-8-openjdk-amd64` doesn't have any `java` and Java 8 is the wrong SDK anyway. I'd agree as far as, that different lines may have different line endings. – Martin Zeitler Oct 31 '22 at 04:06
  • Well. that's your opinion. It's amusing you keep denying the fact that I copied and pasted the Dockerfile to work. – gvisoc Oct 31 '22 at 04:07
  • 1
    Well, it's rather you who ignored that this is based on a NodeJS image, and NodeJS isn't being used. For whatever Java tasks common sense might suggest to start off with a JDK image. When running it cloud-based, the least processing is also cheaper. – Martin Zeitler Oct 31 '22 at 04:10
  • That's fair enough, but not related to the question --and don't get me wrong, I am not saying using a Node as the starting point is fine. When it comes to the directory that is typed in their Dockerfile, that's the right one as it does work. In terms of setting the JAVA_HOME in their Dockerfile, that is the right line, although it can be improved with the export I put in my answer (your `which java` is not enough). I guess once they figure out the mistake they can get to a better base image. – gvisoc Oct 31 '22 at 04:17
1

In a comment, you mentioned:

when I run [RUN ls -lart /usr/lib/jvm/java-8-openjdk-amd64], I get cannot access '/usr/lib/jvm/java-8-openjdk-amd64': No such file or directory

Maybe I'm missing something, but... doesn't that mean that the directory does not exist?

Either you got the path wrong, or (as another answer suggested) there's something in your Dockerfile, probably line endings, that's mangling your lines.

To discard the bit about line endings, try the same command but switching the parameters, i.e.:

RUN ls /usr/lib/jvm/java-8-openjdk-amd64 -lart

If now it whines about unrecognized options, then it's probably a line ending issue (which now affects the t option instead of the directory path).
However, if it still says No such file or directory, then you definitely should check your Java installation path.

walen
  • 7,103
  • 2
  • 37
  • 58
  • To remove any doubt about non-printing characters, you could post a link to a copy of the actual Docker file – g00se Nov 02 '22 at 13:01
  • This seems to have gotten me closer than all of the other suggestions. I appreciate everyone that took a wack at this. I’m still digging into it, but will update the above soon with more info & a link to any follow up questions. Thanks – anonymoose Nov 04 '22 at 19:34
1

It looks like you had some network issues during your first docker build run. It failed to install java, but cached the layer with the attempt. I recommend you to run your build again without caching: docker build -t name --no-cache . and check logging of network operations.

Slava Kuravsky
  • 2,702
  • 10
  • 16