Hello! I hope that this is the right channel, if n...
# android
m
Hello! I hope that this is the right channel, if not please recommend a better place. I am trying to create a CI job in GitLab that runs a build without the Gradle Daemon enabled. Its an Android Kotlin app.
Copy code
variables:
  GRADLE_OPTS: "-Xmx2048m -Dfile.encoding=UTF-8 -Dorg.gradle.daemon=false -Dkotlin.incremental=false -Djava.awt.headless=true -Dorg.gradle.vfs.watch=false"
  JAVA_OPTS: "$GRADLE_OPTS"

build_apk:
  ...
  before_script:
    - chmod +x ./gradlew
    - ./gradlew --version
  script:
    ...
    - export JAVA_OPTS='-Xmx4096m -Xms64m -Dfile.encoding=UTF-8'
    - export JAVA_OPTS="$JAVA_OPTS"
    - export GRADLE_OPTS="$GRADLE_OPTS"
    - ./gradlew assembleRelease --no-daemon --build-cache --configuration-cache
  artifacts:
    ...
I have been at it for a while now, and cannot get it to not do the following:
Copy code
$ ./gradlew assembleRelease --no-daemon --build-cache --configuration-cache
To honour the JVM settings for this build a single-use Daemon process will be forked. For more on this, please refer to <https://docs.gradle.org/9.2.1/userguide/gradle_daemon.html#sec:disabling_the_daemon> in the Gradle documentation.
Daemon will be stopped at the end of the build
What I have tried already: • I set the
org.gradle.jvmargs=-Xmx4096m -Dfile.encoding=UTF-8 -Dorg.gradle.daemon=false
in gradle.properties at root of the project • In gradlew I made
DEFAULT_JVM_OPTS=''
• I set the GRADLE_OPTS and JAVA_OPTS into various matching configurations • Various combinations of the above, following the https://docs.gradle.org/9.2.1/userguide/gradle_daemon.html#sec:disabling_the_daemon • Consulted various AIs So far no luck, what am I missing? Any good resources or even templates to consult, aside from the documentation which did not help so far.
✅ 1
m
Why do you want to disable the daemon in the first place? If you don't want the daemon process to hang around, then single-use daemon shouldn't be too expensive compared to running in the client process
m
I am new, and understood it incorrectly perhaps that CI configs recommended disabling the daemon, What reinforced that belief in me was that I often experienced such build errors:
Copy code
FAILURE: Build failed with an exception.
* What went wrong:
Gradle build daemon disappeared unexpectedly (it may have been killed or may have crashed)
* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Task :app:compileReleaseArtProfile
> Run with --scan to generate a Build Scan (powered by Develocity).
> Get more help at <https://help.gradle.org>.
Since the builds are running on a custom runner I have that in my opinion has enough resources I did not understand why the build occasionally fails due to daemon crashes. Perhaps its something else entirely. How do you see it? What would you recommend?
m
I am new, and understood it incorrectly perhaps that CI configs recommended disabling the daemon,
For common ephemeral CI environments, when the build container is stopped after a single build, there is not so much difference these days. If your CI is stateful, you may either utilize the daemon to get performance benefits, but disable it (or rather use one-shot daemon) for e.g. release builds to be 100% sure no leftover state accidentally spoils them. I don't think there are many strong reasons to run truly single-process builds, leaving starting of the daemon's JVM to Gradle is much easier. Daemon disappearance is often hard to tackle. I can give some pointers, but I don't have a 100% working recipe. Most common reason is hitting limits of the container. Prior to Gradle 9.3.1, it may not play well with container-established memory limits, which leads to kernel's OOM killer stopping the daemon. I only looked into this on mobile kernels, but I suppose kernel or container environment have some logging you can look at to figure out if that's the case. Tweaking
-Xmx
should help; please keep in mind that multiple processes are involved when building Android apps, like Kotlin compiler daemon or test worker daemons. All of those should have configurable memory limits, and has to be tweaked to fit the overall limit imposed by the container. Another source of info is daemon logs, stored in
$GRADLE_USER_HOME/daemon/<gradle-version>/
.
$GRADLE_USER_HOME
is
~/.gradle
by default. Overall, it is unlikely that getting rid of the client process is going to address the memory pressure issue if that's the case.
m
Thanks a lot! I think now its clear I been tackling the wrong problem. My runner is pretty lean on the memory so its likely that was the cause of the issue with the disappearing daemon. Have a nice weekend!