Using parent convention plugin when building just a child project individually?

I refactored my multi-project build to introduce the buildSrc and create a conventions plug-in, along with a versions catalog using libs.versions.toml. Everything works fine for all projects when I run the build from parent project, but if I try running an isolated build on a child project it can’t find the plug-in. giving error

Plugin [id 'myproject-conventions'] was not found in any of the following sources:

If I’m understanding things correctly, it’s because the plugin isn’t compiled and doesn’t actually exist when running the child build just at the lower level.
So is there some simple way I’m missing to make the child project aware of the parent’s buildSrc/convention plug-in?
Something like referencing …/parent/buidSrc somewhere in the child project even though I recognize that would introduce a coupling and dependency that is generally discouraged.

There are multiple possibilities, but my actual answer depends on some more details.

What do you mean by “if I try running an isolated build on a child project”?
How does your build layout look like and which settings scripts with which content do you have?

For running an isolated build,
I mean cd to the child project directory and run any gradle command. Even something basic like ‘gradle tasks’ doesn’t work because the plugin doesn’t resolve and give the above error when just evaluating what to do.

Similarly if navigate in the gradle project tree to run a child task directly in IntelliJ as shown in the screenshot. Green tasks work, anything in X, or the other child projects do not

Apologies, I’m not sure what you mean by “which settings scripts/content”

Apologies, I’m not sure what you mean by “which settings scripts/content”

Please show the paths and content of all settings.gradle or settings.gradle.kts files.
If there is sensitive content, actually the paths and the include and includeBuild statements are what I’m interested in to verify a suspicion I have.

//Directory Structure for MyProject
./build.gradle
./settings.gradle

./buildsrc/build.gradle
./buildSrc/src/main/groovy/myproject-conventions.gradle

./myapp-common/build.gradle
./myapp-common/settings.gradle

./myapp/build.gradle
./myapp/settings.gradle
./myapp/settings-parent.gradle //why? I don't know...

./myapp/core/build.gradle
./myapp/ear/build.gradle
./myapp/web/build.gradle

Comments:

  • All settings files are below, in their entirety.
  • web,ear,core sub-sub-projects don’t have their own settings file
  • the special: settings-parent.gradle looks wrong to me, I don’t know why that would be needed. (I inherited this project)
  • I think there is a better way now to add the project() dependencies… (includeBuild?)
//===============================
//MyProject/settings.gradle
//===============================
pluginManagement {
     repositories {
        maven { url '[we are restricted to just internal corporate artifactory servers]'
            credentials {
                username = "$(artifactory_id)"
                password = "$(artifactory_pw)"

            }
        }           
    }
}
include 'myapp-common'
apply from: 'myapp/settings-parent.gradle'
rootProject. name = 'MyProject'

project (':myapp-core').projectDir = new File (rootDir, 'myapp/core')
project (':myapp-web').projectDir = new File (rootDir, 'myapp/web')
project (':myapp-ear').projectDir = new File (rootDir, 'myapp/ear')
project (':myapp-common').projectDir = new File (rootDir, 'myapp-common' )
//===============================
//MyProject/myapp/settings.gradle
//===============================
rootProject.name = 'myapp'
include 'web', 'core', 'ear'
//=====================================
//MyProject/myapp/settings-parent.gradle
//======================================
rootProject.name = 'myapp'
include 'myapp-web', 'myapp-core', 'myapp-ear'
//=====================================
//MyProject/myapp-common/settings.gradle
//=====================================
rootProject.name = 'myapp-common'

So yeah, my suspicion was correct.
You include myapp-common, core, ear, and web in multiple builds.
Never ever ever ever ever ever ever do that.
One project should always be at most included in exactly one build.
If you need a project in another build, then include that whole build into the other build using includeBuild, forming a composite build.

Besides that, buildSrc is only available for the one build where it is part of. Not for other builds that might include the same project (which you should never ever do anyway as described), nor for included builds if you form a composite build after reading this.

Instead rename buildSrc to something else, give it a settings script that it should have anyway like every build should, and then use includeBuild within pluginManagement { ... } of the builds where you want to use that plugin, because using an included build instead of buildSrc you can freely include that build into multiple other builds.


Btw. I strongly recommend switching to Kotlin DSL. By now it is the default DSL, you immediately get type-safe build scripts, actually helpful error message if you mess up the syntax, and amazingly better IDE support if you use a good IDE like IntelliJ IDEA or Android Studio.