Invalid implicit dependency when relocating build output through init.d script

project.zip (3.0 KB)

When minimal example in attached zip is extracted and ‘gradle build’ is run, it is successful.

When build output is redirected using this init script at $GRADLE_USER_HOME/init.d/mysetup.gradle

allprojects {
    def curDir = System.getProperty("user.dir")
    def gradleUserHome = System.getenv("GRADLE_USER_HOME")

    buildDir = gradleUserHome + "/userbuilds" + curDir + "/build"

    println("buildDir = " + buildDir)
}

‘gradle build’ on same project throws this error

  • Gradle detected a problem with the following location: ‘/home/jbuild/userbuilds/lang/java/build/gradle/sample/minimal/build/classes/java/main’.

    Reason: Task ‘:folderb:hello:jar’ uses this output of task ‘:foldera:compileJava’ without declaring an explicit or implicit dependency. This can lead to incorrect results being produced, depending on what order the tasks are executed.

    Possible solutions:

    1. Declare task ‘:foldera:compileJava’ as an input of ‘:folderb:hello:jar’.
    2. Declare an explicit dependency on ‘:foldera:compileJava’ from ‘:folderb:hello:jar’ using Task#dependsOn.
    3. Declare an explicit dependency on ‘:foldera:compileJava’ from ‘:folderb:hello:jar’ using Task#mustRunAfter.

Version of gradle I am using:


Gradle 8.10

Build time: 2024-08-14 11:07:45 UTC
Revision: fef2edbed8af1022cefaf44d4c0514c5f89d7b78

Kotlin: 1.9.24
Groovy: 3.0.22
Ant: Apache Ant™ version 1.10.14 compiled on August 16 2023
Launcher JVM: 17.0.12 (Azul Systems, Inc. 17.0.12+7-LTS)
Daemon JVM: /usr/lib/jvm/zulu17-ca-amd64 (no JDK specified, using current Java home)
OS: Linux 5.15.0-122-generic amd64

I’m confused, what do you expect if you set the buildDir of all projects in a build to the same directory?
Of course this results in a great f***up.
You should probably somewhere incorporate the project path.

Besides that, using the user.dir is also an extremely bad idea.
Just like using the File(...) constructor with a relative path it uses the current working directory of the JVM, which is the daemon JVM.
This is not directly related to the current user directory which operates the CLI or maybe is using an IDE or other integration, and it is also just lightly related to the root project’s project directory. The daemon most often tries to set this directory to the root project directory, but this does not work in all cases and not everywhere. Most JVM code, including Gradle logic is inherently broken when relying on the current working directory anyway. The only valid case I have in mind right now for using the current working directory is, if you develop a commandline utility and the relative path you try to resolve is coming in as argument on the commandline.

Your intention probably was to use the root project directory, but even that is a bad idea unless you further segregate per project, as that is most probably what you got now and all projects in one build share the same buildDir. If you use layout.projectDirectory instead, you probably achieve better what you intended for whatever reason.