A real practice to handle “unrelated build file” error from Gradle

Edward Zhou
Tech Life & Fun
Published in
3 min readSep 23, 2020
Photo by Nathan Anderson on Unsplash

Background

I have been maintaining a Jenkins job (along with a customized Python library) which builds different components and then, with the help of Gradle, export some of generated files (in a zip) to a Artifactory repository. One day I was told that there is a new error reported from the job when a new component (called “actor”) starts to use it.

It looks like:

Build file ‘/src/actor/export/export.gradle’ is not part of the build defined by settings file /src/actor/settings.gradle’. If this is an unrelated build, it must have its own settings file.

The job works pretty fine with all existing components so the first thing in my mind is that the error is connected with the new component. It turns out the new component itself also relies on Gradle to build. Its build script looks like:

python customizedLib/export.py <<<the export helper in customzied Python lib

gradle build <<<where the error occurs

Basically export.py will generate a export.gradle under /src/actor/export/, and then ask Gradle to use /src/actor/export/export.gradle to perform exporting operations.

Investigation

Above workflow looks pretty simple and since I myself am not a Gradle expert, it looks pretty normal to me.

So I googled and came across to some similar questions like https://stackoverflow.com/questions/56293162/build-gradle-is-not-part-of-the-build-defined-by-settings-file.

However, the solutions I found are either not fitting to my context or too complicated to understand (not to mention implementing). I think it’s due to my limited knowledge of Gradle so I just take a quick browse on Gradle official documents and get caught by below words (from https://docs.gradle.org/current/userguide/build_lifecycle.html#sec:initialization):

If you execute Gradle from within a project with no settings.gradle file, Gradle looks for a settings.gradle file in the following way:

It looks in a directory called master which has the same nesting level as the current dir.

If not found yet, it searches parent directories.

If not found yet, the build is executed as a single project build.

If a settings.gradle file is found, Gradle checks if the current project is part of the multi-project hierarchy defined in the found settings.gradle file. If not, the build is executed as a single project build. Otherwise a multi-project build is executed.

This clearly states the internal working mechanism and shed the light on how to resolve this “unrelated build file” problem: since the new component (“actor”) itself is using Gradle to build and there is a settings.gradle under its root (/src/actor/), even my Jenkins job runs “gradle -b export.gradle export” in /src/actor/export/, Gradle will treat it as a part of a multi-project build so it will refer to /src/actor/settings.gradle to see how to build this multi-project build. However, since actor is totally unaware of the existence of export.gradle (it’s generated on the fly by the Python library) and by its own logic it’s not necessary to treat export as part of its build, there will be ZERO information regardin export (like, for example, include export) in /src/actor/settings.gradle. Therefore Gradle will throw the error because of this conflict.

Solution

Given above working mechanism of Gradle and the problem context, it’s pretty easy to resolve this. Since the export is needed by my Jenkins job and actually not a part of the component it facilitates, I should keep excluding it from the awareness of the component. So no change is needed on /src/actor/settings.gradle.

Instead, during the creation of export.gradle (under /src/actor/export/), I will instruct the Jenkins job to create an empty settings.gradle in the same folder, so that when Gradle starts to execute “gradle -b export.gradle export” it will treat export as a separate single Gradle project build although it resides under /src/actor which itself is a Gradle multi-project builld.

--

--