I am trying to build image for Android project for CI configuration (this will be the first step in my pipeline)
I am trying to run this command:
docker build -t android-build:some-name -f Dockerfile .
Below is my Dockerfile:
FROM openjdk:11.0.7
ENV SDK_URL="https://dl.google.com/android/repository/sdk-tools-linux-3859397.zip" \
ANDROID_HOME="/usr/local/android-sdk" \
ANDROID_VERSION=29 \
ANDROID_BUILD_TOOLS_VERSION=28.0.3
RUN mkdir "$ANDROID_HOME" .android \
&& cd "$ANDROID_HOME" \
&& curl -o sdk.zip $SDK_URL \
&& unzip sdk.zip \
&& rm sdk.zip \
&& yes | $ANDROID_HOME/tools/bin/sdkmanager --licenses
RUN $ANDROID_HOME/tools/bin/sdkmanager --update
RUN $ANDROID_HOME/tools/bin/sdkmanager "build-tools;${ANDROID_BUILD_TOOLS_VERSION}" \
"platforms;android-${ANDROID_VERSION}" \
"platform-tools"
RUN mkdir /application
WORKDIR /application
I am getting error as below:
Exception in thread "main" java.lang.NoClassDefFoundError: javax/xml/bind/annotation/XmlSchema
11:11:42
at com.android.repository.api.SchemaModule$SchemaModuleVersion.<init>(SchemaModule.java:156)
11:11:42
at com.android.repository.api.SchemaModule.<init>(SchemaModule.java:75)
11:11:42
at com.android.sdklib.repository.AndroidSdkHandler.<clinit>(AndroidSdkHandler.java:81)
11:11:42
at com.android.sdklib.tool.SdkManagerCli.main(SdkManagerCli.java:117)
11:11:42
at com.android.sdklib.tool.SdkManagerCli.main(SdkManagerCli.java:93)
11:11:42
Caused by: java.lang.ClassNotFoundException: javax.xml.bind.annotation.XmlSchema
11:11:42
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
11:11:42
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178) [0m [91m
11:11:42
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
11:11:42
... 5 more
11:11:42
The command '/bin/sh -c mkdir "$ANDROID_HOME" .android && cd "$ANDROID_HOME" && curl -o sdk.zip $SDK_URL && unzip sdk.zip && rm sdk.zip && yes | $ANDROID_HOME/tools/bin/sdkmanager --licenses' returned a non-zero code: 1
11:11:42
[0m
I was trying also another configuration:
FROM openjdk:11.0.7
ENV SDK_URL="https://dl.google.com/android/repository/commandlinetools-linux-6604631_latest.zip" \
ANDROID_HOME="/usr/local/android-sdk" \
ANDROID_VERSION=29 \
ANDROID_BUILD_TOOLS_VERSION=28.0.3 \
RUN mkdir "$ANDROID_HOME" .android \
&& cd "$ANDROID_HOME" \
&& curl -o sdk.zip $SDK_URL \
&& unzip sdk.zip \
&& rm sdk.zip
RUN yes | $ANDROID_HOME/cmdline-tools/bin/sdkmanager --sdk_root=$ANDROID_HOME --licenses
RUN $ANDROID_HOME/cmdline-tools/bin/sdkmanager --sdk_root=$ANDROID_HOME --update
RUN yes | $ANDROID_HOME/cmdline-tools/bin/sdkmanager --sdk_root=$ANDROID_HOME \
"build-tools;${ANDROID_BUILD_TOOLS_VERSION}" \
"platforms;android-${ANDROID_VERSION}"
RUN mkdir /application
WORKDIR /application
But this gives me an error as below:
Error response from daemon: failed to parse Dockerfile: Syntax error - can't find = in "RUN". Must be of the form: name=value
11:22:51
Process exited with code 1
Unfortunately I am not a DevOps guy, so what is wrong with my configuration?
Could anyone help?
You have two option to fix this issue
Downgrade JDK so you will have the required module for SDK as these are removed in JDK 9+
Or use new SDK that does work with JDK 9+
FROM openjdk:8
ENV SDK_URL="https://dl.google.com/android/repository/sdk-tools-linux-3859397.zip" \
ANDROID_HOME="/usr/local/android-sdk" \
ANDROID_VERSION=29 \
ANDROID_BUILD_TOOLS_VERSION=28.0.3
RUN mkdir "$ANDROID_HOME" .android \
&& cd "$ANDROID_HOME" \
&& curl -o sdk.zip $SDK_URL \
&& unzip sdk.zip \
&& rm sdk.zip \
&& yes | $ANDROID_HOME/tools/bin/sdkmanager --licenses
RUN $ANDROID_HOME/tools/bin/sdkmanager --update
RUN $ANDROID_HOME/tools/bin/sdkmanager "build-tools;${ANDROID_BUILD_TOOLS_VERSION}" \
"platforms;android-${ANDROID_VERSION}" \
"platform-tools"
RUN mkdir /application
WORKDIR /application
Or you can look into this for new SDK
Google has been working on a new Android SDK Command-line Tools release that runs on current JVMs (9, 10, 11+) and does not depend on deprecated JAXB EE modules!
SDK Tools for Linux
Related
i am facing some annoying issue. I am working in a project, where the base is kotlin with a external module in react (0.61.5). Works perfect with config: Plugin 4.0.1 & Gradle 6.6, but we implemented a new module (this module is in compose), so we had to update to gradle 7.X + and app started crashing.
Error: Unable to load script.Make sure you are either running a Metro server or that your bundle 'index.android.bundle' is packaged correctly for release & Unable to extract native debug metadata.
Current Config: Plugin 7.2.2 & Gradle 7.5.2
React: 0.61.5
Please let me know if is fixed, need help!!!!!
PS: For release build, we use a docker image, follow
FROM ubuntu:20.04
ENV DEBIAN_FRONTEND=noninteractive
# Replace shell with bash so we can source files
RUN rm /bin/sh && ln -s /bin/bash /bin/sh
# Aliases
RUN alias l="ls -altr"
# set default build arguments
ARG SDK_VERSION=commandlinetools-linux-8512546_latest.zip
ARG ANDROID_BUILD_VERSION=31
ARG ANDROID_TOOLS_VERSION=31.0.0
ARG BUCK_VERSION=2022.05.05.01
ARG NDK_VERSION=21.4.7075529
ARG NODE_VERSION=10.16.3
ARG WATCHMAN_VERSION=4.9.0
ARG CMAKE_VERSION=3.18.1
# nvm environment variables
ENV NVM_DIR /usr/local/nvm
# set default environment variables, please don't remove old env for compatibilty issue
ENV ADB_INSTALL_TIMEOUT=10
ENV ANDROID_HOME=/opt/android
ENV ANDROID_SDK_ROOT=${ANDROID_HOME}
ENV ANDROID_NDK=${ANDROID_HOME}/ndk/$NDK_VERSION
ENV JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
ENV CMAKE_BIN_PATH=${ANDROID_HOME}/cmake/$CMAKE_VERSION/bin
ENV PATH=${ANDROID_NDK}:${CMAKE_BIN_PATH}:${ANDROID_HOME}/cmdline-tools/latest/bin:${ANDROID_HOME}/emulator:${ANDROID_HOME}/platform-tools:${ANDROID_HOME}/tools:${ANDROID_HOME}/tools/bin:/opt/buck/bin/:${PATH}
# Install system dependencies
RUN apt update -qq && apt install -qq -y --no-install-recommends \
apt-transport-https \
curl \
file \
gcc \
git \
g++ \
gnupg2 \
libc++1-10 \
libgl1 \
libtcmalloc-minimal4 \
make \
openjdk-11-jdk-headless \
openssh-client \
patch \
python3 \
python3-distutils \
rsync \
ruby \
ruby-dev \
tzdata \
unzip \
sudo \
ninja-build \
zip \
# Dev libraries requested by Hermes
libicu-dev \
# Emulator & video bridge dependencies
libc6 \
libdbus-1-3 \
libfontconfig1 \
libgcc1 \
libpulse0 \
libtinfo5 \
libx11-6 \
libxcb1 \
libxdamage1 \
libnss3 \
libxcomposite1 \
libxcursor1 \
libxi6 \
libxext6 \
libxfixes3 \
zlib1g \
libgl1 \
pulseaudio \
socat \
&& gem install bundler \
&& rm -rf /var/lib/apt/lists/*;
# Install nvm
RUN curl --silent -o- https://raw.githubusercontent.com/creationix/nvm/v0.31.2/install.sh | bash
# Install node and npm
RUN source $NVM_DIR/nvm.sh \
&& nvm install $NODE_VERSION \
&& nvm alias default $NODE_VERSION \
&& nvm use default \
&& ln -s "$(which node)" /usr/local/bin/node
# Add node and npm to path so the commands are available
ENV NODE_PATH $NVM_DIR/v$NODE_VERSION/lib/node_modules
ENV PATH $NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH
# Install NPM Stuff
RUN npm install -g yarn
RUN npm install -g firebase-tools
# download and install buck using the java11 pex from Jitpack
RUN curl -L https://jitpack.io/com/github/facebook/buck/v${BUCK_VERSION}/buck-v${BUCK_VERSION}-java11.pex -o /tmp/buck.pex \
&& mv /tmp/buck.pex /usr/local/bin/buck \
&& chmod +x /usr/local/bin/buck
# Install SDK & NDK
RUN curl -sS https://dl.google.com/android/repository/${SDK_VERSION} -o /tmp/sdk.zip \
&& mkdir -p ${ANDROID_HOME}/cmdline-tools \
&& unzip -q -d ${ANDROID_HOME}/cmdline-tools /tmp/sdk.zip \
&& mv ${ANDROID_HOME}/cmdline-tools/cmdline-tools ${ANDROID_HOME}/cmdline-tools/latest \
&& rm /tmp/sdk.zip \
&& yes | sdkmanager --licenses \
&& yes | sdkmanager "platform-tools" \
"emulator" \
"platforms;android-$ANDROID_BUILD_VERSION" \
"build-tools;$ANDROID_TOOLS_VERSION" \
"cmake;$CMAKE_VERSION" \
"system-images;android-21;google_apis;armeabi-v7a" \
"ndk;$NDK_VERSION" \
&& rm -rf ${ANDROID_HOME}/.android \
&& chmod 777 -R /opt/android \
&& ln -s ${ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64/lib64/clang/9.0.9 ${ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64/lib64/clang/9.0.8
Try this:
1- add classpath('com.android.tools.build:gradle:7.0.3') in your dependencies located in android/build.gradle
basically the gradle version is not compatible with react native on android at the time of posting this answer.
2- If that doesn't work, before doing build, run:
npx react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle
then:
cd android
./gradlew assembleRelease
This github issue can give you more information.
We are configuring a self-hosted android runner for GithubActions, but when we run some command of gradlew, it crashes/stops sending an error connection reset.
Our docker file contains the basic for a android runner (few lines of code for gradle and sdk installation. the tools are also installed properly).
# Gradle
ENV GRADLE_VERSION 7.0.2
ENV GRADLE_HOME="/opt/gradle"
ENV GRADLE_SDK_URL https://services.gradle.org/distributions/gradle-${GRADLE_VERSION}-bin.zip
RUN curl -sSL "${GRADLE_SDK_URL}" -o gradle-${GRADLE_VERSION}-bin.zip \
&& unzip -q gradle-${GRADLE_VERSION}-bin.zip -d ${GRADLE_HOME} \
&& rm -rf gradle-${GRADLE_VERSION}-bin.zip \
&& chmod +775 /opt/gradle
ENV PATH ${GRADLE_HOME}/bin:$PATH
# Install Android SDK
RUN echo "SDK tools ${ANDROID_SDK_TOOLS_VERSION}" \
&& cd /opt \
&& chmod +775 . \
&& wget -q "https://dl.google.com/android/repository/commandlinetools-linux-${ANDROID_SDK_TOOLS_VERSION}_latest.zip" -O android-commandline-tools.zip \
&& mkdir -p ${ANDROID_SDK_HOME}/cmdline-tools \
&& unzip -q android-commandline-tools.zip -d /tmp/ \
&& mv /tmp/cmdline-tools/ ${ANDROID_SDK_HOME}/cmdline-tools/latest \
&& rm android-commandline-tools.zip && ls -la ${ANDROID_SDK_HOME}/cmdline-tools/latest/
Then when in the workflow we do some ./gradlew command it crashes.
some example commands that crash:
> ./gradlew --version
> ./gradlew app:assembleBetaRelease --offline
Always same Error log:
Run ./gradlew --version
Downloading https://services.gradle.org/distributions/gradle-7.0.2-all.zip
Exception in thread "main" java.lang.RuntimeException: java.net.SocketException: Connection reset
at org.gradle.wrapper.ExclusiveFileAccessManager.access(ExclusiveFileAccessManager.java:78)
at org.gradle.wrapper.Install.createDist(Install.java:47)
at org.gradle.wrapper.WrapperExecutor.execute(WrapperExecutor.java:129)
at org.gradle.wrapper.GradleWrapperMain.main(GradleWrapperMain.java:48)
Caused by: java.net.SocketException: Connection reset
at java.base/java.net.SocketInputStream.read(SocketInputStream.java:186)
at java.base/java.net.SocketInputStream.read(SocketInputStream.java:140)
at java.base/sun.security.ssl.SSLSocketInputRecord.read(SSLSocketInputRecord.java:478)
at java.base/sun.security.ssl.SSLSocketInputRecord.readHeader(SSLSocketInputRecord.java:472)
at java.base/sun.security.ssl.SSLSocketInputRecord.decode(SSLSocketInputRecord.java:160)
at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:111)
at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1426)
at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1336)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:450)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:421)
at java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:572)
at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:197)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1592)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1520)
at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:250)
at org.gradle.wrapper.Download.downloadInternal(Download.java:59)
at org.gradle.wrapper.Download.download(Download.java:45)
at org.gradle.wrapper.Install$1.call(Install.java:60)
at org.gradle.wrapper.Install$1.call(Install.java:47)
at org.gradle.wrapper.ExclusiveFileAccessManager.access(ExclusiveFileAccessManager.java:65)
... 3 more
Error: Process completed with exit code 1.
It seems that tries to download Gradle, but it exist previously in dockerfile.
Did we forget some configuration in dockerfile or something similar?
I am trying to set up a CI/CD pipeline for my android project using Jenkins and docker(I'm using docker file) and here's a sample of the Jenkinsfile
pipeline {
agent { dockerfile true }
environment {
appName = 'Yoruba Proverbs'
KEY_PASSWORD = credentials('keyPassword')
KEY_ALIAS = credentials('keyAlias')
KEYSTORE = credentials('keystore')
STORE_PASSWORD = credentials('storePassword')
}
stages {
....
}
}
The build fails at the instance when docker is trying to make a modification under the workspace directory with an operation not permitted error(FileSystemException). Here's a screenshot: build
I have tried a few different tweaks like restarting Jenkins, restarting docker, Granting docker full disk access on my laptop but no positive result
Edit:
This is the content of the Dockerfile
FROM openjdk:8
WORKDIR project/
# Install Build Essentials
RUN apt-get update \
&& apt-get install build-essential -y
# Set Environment Variables
ENV SDK_URL="https://dl.google.com/android/repository/sdk-tools-linux-3859397.zip" \
ANDROID_HOME="/usr/local/android-sdk" \
ANDROID_VERSION=30
# Download Android SDK
RUN mkdir "$ANDROID_HOME" .android \
&& cd "$ANDROID_HOME" \
&& curl -o sdk.zip $SDK_URL \
&& unzip sdk.zip \
&& rm sdk.zip \
&& mkdir "$ANDROID_HOME/licenses" || true \
&& echo "24333f8a63b6825ea9c5514f83c2829b004d1fee" > "$ANDROID_HOME/licenses/android-sdk-license" \
&& yes | $ANDROID_HOME/tools/bin/sdkmanager --licenses
# Install Android Build Tool and Libraries
RUN $ANDROID_HOME/tools/bin/sdkmanager --update
RUN $ANDROID_HOME/tools/bin/sdkmanager "build-tools;30.0.3" \
"platforms;android-${ANDROID_VERSION}" \
"platform-tools"
CMD ["/bin/bash"]
I am trying to build a docker image for android, below is my docker file
FROM ubuntu:18.04
LABEL maintainer="Javier Santos"
ENV VERSION_SDK_TOOLS "4333796"
ENV ANDROID_HOME "/sdk"
ENV PATH "$PATH:${ANDROID_HOME}/tools"
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get -qq update
RUN apt-get install -y locales
RUN locale-gen en_US.UTF-8
ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' LC_ALL='en_US.UTF-8'
RUN apt-get install -qqy --no-install-recommends \
bzip2 \
curl \
git-core \
html2text \
openjdk-8-jdk \
libc6-i386 \
lib32stdc++6 \
lib32gcc1 \
lib32ncurses5 \
lib32z1 \
unzip \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN rm -f /etc/ssl/certs/java/cacerts; \
/var/lib/dpkg/info/ca-certificates-java.postinst configure
RUN curl -s https://dl.google.com/android/repository/sdk-tools-linux-${VERSION_SDK_TOOLS}.zip > /sdk.zip && \
unzip /sdk.zip -d /sdk && \
rm -v /sdk.zip
RUN mkdir -p $ANDROID_HOME/licenses/ \
&& echo "8933bad161af4178b1185d1a37fbf41ea5269c55\nd56f5187479451eabf01fb78af6dfcb131a6481e" > $ANDROID_HOME/licenses/android-sdk-license \
&& echo "84831b9409646a918e30573bab4c9c91346d8abd" > $ANDROID_HOME/licenses/android-sdk-preview-license
RUN yes | $ANDROID_HOME/tools/bin/sdkmanager "platforms;android-28"
ADD packages.txt /sdk
RUN mkdir -p /root/.android && \
touch /root/.android/repositories.cfg && \
${ANDROID_HOME}/tools/bin/sdkmanager --update
RUN while read -r package; do PACKAGES="${PACKAGES}${package} "; done < /sdk/packages.txt && \
${ANDROID_HOME}/tools/bin/sdkmanager ${PACKAGES}
But when I am building this, then Sending build context to Docker daemon is getting larger from 250GB and still increasing, Is this normal, or I am doing something wrong, please suggest, thanks in advance
I have taken reference from this link https://hub.docker.com/r/javiersantos/android-ci
The build context is not inside your Dockerfile, it's the path passed at the end of the build command, often a . to indicate the current directory. When building with compose it defaults to the current directory. So if this is growing, you have files in that context directory that are growing between builds.
With buildkit, this behavior changes, only sending the requested files rather than the full context. You can enable that by running export DOCKER_BUILDKIT=1 in the shell that runs the docker build command. You can also default this feature to enabled by setting the following in /etc/docker/daemon.json and then reloading the docker engine (often systemctl reload docker):
{
"features": {"buildkit": true }
}
Considering your build only adds a single file, probably the best option is to configure a .dockerignore in the root of your context (the same folder with the packages.txt file) with the following:
*
!packages.txt
The * ignores everything, and the !packages.txt reincludes that file back into the context.
so im trying to build my app on release mode with Docker.
When I run it on my machine it works with no problem but when I run it on docker I get this error:
Error: spawnSync ./gradlew ENOBUFS
[11:15:54] : [Step 1/2] at Object.spawnSync (internal/child_process.js:1041:20)
[11:15:54] : [Step 1/2] at spawnSync (child_process.js:607:24)
[11:15:54] : [Step 1/2] at execFileSync (child_process.js:634:15)
[11:15:54] : [Step 1/2] at runOnAllDevices (/usr/src/app/node_modules/#react-native-community/cli-platform-android/build/commands/runAndroid/runOnAllDevices.js:74:39)
[11:15:54] : [Step 1/2] at buildAndRun (/usr/src/app/node_modules/#react-native-community/cli-platform-android/build/commands/runAndroid/index.js:158:41)
[11:15:54] : [Step 1/2] at /usr/src/app/node_modules/#react-native-community/cli-platform-android/build/commands/runAndroid/index.js:125:12
[11:15:54] : [Step 1/2] at processTicksAndRejections (internal/process/task_queues.js:93:5)
[11:15:54] : [Step 1/2] at async Command.handleAction (/usr/src/app/node_modules/react-native/node_modules/#react-native-community/cli/build/cliEntry.js:160:7)
when I try to build with develop im getting no problems...
another thing I put attention about is when I build my app on docker with ./gradlew installRelease I get no issue but this command never use Jetifier which I really need for my build.
Im attaching my docker file, let me know if you need more files:
ENV SDK_URL "https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip"
ENV ANDROID_HOME /usr/src/app
ENV ANDROID_BUILD_TOOLS_VERSION 28.0.3
ENV ANDROID_VERSION 28
ENV PATH $PATH:$ANDROID_HOME/bin
ARG NODE_VERSION=12.x
WORKDIR /usr/src/app
COPY package*.json ./
RUN cat package.json
# installing android and java
RUN apt update -qq && apt install -qq -y --no-install-recommends \
apt-transport-https \
curl \
build-essential \
file \
git \
openjdk-8-jre \
gnupg2 \
python \
ruby-full \
openssh-client \
zip \
unzip \
sudo \
&& rm -rf /var/lib/apt/lists/*;
RUN curl -sL -o android.zip ${SDK_URL} && unzip android.zip && rm android.zip
RUN yes | $ANDROID_HOME/tools/bin/sdkmanager --licenses
# install nodejs and yarn packages from nodesource and yarn apt sources
RUN echo "deb https://deb.nodesource.com/node_${NODE_VERSION} stretch main" > /etc/apt/sources.list.d/nodesource.list \
&& echo "deb https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \
&& curl -sS https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - \
&& curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
&& apt-get update -qq \
&& apt-get install -qq -y --no-install-recommends nodejs yarn \
&& rm -rf /var/lib/apt/lists/*
RUN npm i -g react-native-cli
#installing libraries
RUN npm install
COPY . .
#Create apk and zip it with the current date (UTC)
RUN react-native run-android --variant=release; exit 0
RUN cd android && cd app && cd build && cd outputs && cd apk && cd release && zip -r `(date +%m_%d_%Y__%H:%M)`.zip app-release.apk
#Create a new container from a linux base image that has the aws-cli installed
FROM mesosphere/aws-cli
#Using the alias defined for the first container, copy the contents of the build folder to this container
COPY --from=builder /usr/src/app/android/app/build/outputs/apk/release/ .
COPY --from=builder /usr/src/app/deploy-android-prod.sh .
ENTRYPOINT chmod +x deploy-android-prod.sh && sh ./deploy-android-prod.sh
Thanks for the help