I am trying to understand includeBuild, and build-...
# plugin-development
l
I am trying to understand includeBuild, and build-logic vs buildSrc. I was able to get an example working with a single included build producing one plugin But If I attempt to includeBuild a second directory i goes wrong. Specifically in this example (attached zip): build-logic-a, has two sub projects and builds fine. Both plugins can be seen by my app project. build-logic-b, doesn't get built at all, and results in a
Plugin with id 'my-java-convention-b' not found.
error. If i comment out the application of
my-java-convention-b
in
app\build.gradle
and run
projects
it shows both includeBuilds loaded. So I am really confused. Yes, I could move
build-logic-b\convention
to
build-logic-a\convention-b
but that doesn't solve the actual issue. To explain the actual issue, I am trying to reorganize a very large project into multiple projects with shared sources. Using a hybrid of an external java-gradle-plugin and a in-repo build-logic project. I can get the in-repo build-logic to work, and reference the built external plugin, however the issue comes when i try to develop both at the same time.
Copy code
includeBuild 'build-logic'
    includeBuild 'forgedev' // Checked out in a sub-directory, could be anywhere
Results in the normal build-logic gradle file not being able to be compiled with tons of errors saying it cant find groovy. Commenting out the 2nd includeBuild fixes the compile issues. So ya, there are two issues. The first is when trying to make a test workspace, the second is when trying to integrate into a real project. Maybe im missing something really simple, but I tried searching the gradle github and didn't find anything says that only one includeBuild works for build-logic. On the contrary I've found tons of examples of it saying that multiple work. Ive been going at this for all weekend, and finally exhausted what i can figure out myself.
v
:build-logic-b:convention
and
:build-logic-b:convention
both build an artifact with coordinates
com.example.buildlogic:convention
and this is what is causing what you see. An included build is like when you have the build separate, build it, publish it to some repository and then consume the artifact by coordinates. With the included builds and the plugins, Gradle searches for the plugin IDs in the included builds and then adds dependencies for those coordinates automatically. So the
id 'my-java-convention-a'
and the
id 'my-java-convention-b'
both cause the dependency
com.example.buildlogic:convention
to be added to the build script classpath. But then only the one from A is built and added as this already provides the requested coordinates. So you either need to change the
group
in one of the builds, or the artifact name and thus (to be clean) the project name, so that each of the produced artifacts has unique coordinates. Btw. you should add a namespace to your convention plugins either by having a package statement in the scripts or by naming the files with some dot in it. Plugin IDs without namespace (i.e. without dot) should stay reserved to built-in plugins to not risk some naming clash in the future for example if a built-in plugin with the same name gets added.
l
That makes total sense now that I am fully rested. Changing the name of the second include to conventionb solved the issue in the example. Ya, in production our plugins will be under our own group (net.minecraftforge) to prevent clashing. Any chance you have an idea on my second issue, where includeBuild of the <Z:\Projects\Forge_262\forgedev|ForgeDevPlugin> causes existing functional build-logic to fail to compile? This is reproduceable in the same zip I provided by changing the 2nd include to
includeBuild('ForgeDevPlugin')
and running
git clone <https://github.com/MinecraftForge/ForgeDevPlugin.git>
Then refreshing the project will cause
:build-logic-a:convention:compileJava
to fail
v
Oh, missed the second part, should have read the post fully, sorry. Just looking, at --info output says
Copy code
Task ':build-logic-a:convention:compileJava' is not up-to-date because:
  Input property 'classpath' file D:\Dateien\.gradle\caches\9.0.0\generated-gradle-jars\gradle-api-9.0.0.jar has been removed.
  Input property 'classpath' file D:\Dateien\.gradle\wrapper\dists\gradle-9.0.0-bin\d6wjpkvcgsg3oed0qlfss3wgl\gradle-9.0.0\lib\groovy-4.0.27.jar has been removed.
  Input property 'classpath' file D:\Dateien\.gradle\wrapper\dists\gradle-9.0.0-bin\d6wjpkvcgsg3oed0qlfss3wgl\gradle-9.0.0\lib\groovy-ant-4.0.27.jar has been removed.
  and more...
which looks very suspicious but also explains that the types are not found on compilation.
Yep, compile classpath became completely empty for some reason 😱
ForgeDevPlugin has in its gradle.properties
<http://systemProp.org|systemProp.org>.gradle.unsafe.suppress-gradle-api=true
This stays set and thus influences the other builds in the same JVM
l
Ya thats what I was able to find, trying to strip down the ForgeDevPlugin to see where it is coming from. See if I can get a minimal reproduction. I'm sure its another dumb thing we're doing on our end. But it just seems weird that two projects can override eachother. ... whelp that would probably cause it. will need to see how to undo that if it happens to have been done elseware.
Okay, so good news I can simply add back the gradleApi and it seems to work fine. So at least I can get back on to things. Gunna grumble at the other team member who was out with covid over my inability to see that system prop.
Copy code
dependencies {
    implementation gradleApi()
}
Back again, i've got things functional but now trying for some quality of life things. Mainly trying to get IntelliJ linting/suggestions to work with plugins applied in the build-logic projects. Is there something I am missing? Overall I'm just trying to split a very large build script into multiple reusable parts. For example, I don't want to duplicate this code across all the sub-projects
v
I'd assume that's something to report to JetBrains in their YouTrack. I never used precompiled Groovy DSL script plugins. And the same as Kotlin DSL version in the same project works just fine, so the dependencies are there. Just not treated properly in the Groovy DSL script plugin it seems.
But besides reporting it, you should also consider to not use Groovy DSL, but Kotlin DSL. You immediately get type-safe build scripts, actually helpful error messages if you mess up the syntax, and amazingly better IDE support if you use a good IDE.
I write any build-local build scripts or build logic since years with Kotlin DSL only, or in normal Kotlin files. Only for published plugins I would always choose plain Java for better compatibility and less fuckup.
l
I've thought about switching to kotlin, but honestly groovy is just easier to use. Especially if you don't rely on IDE integration. I am an Eclipse user so no IDE integration for either, but others on the team are IntelliJ so I was hoping to get them something that worked nice. Just wanted to be sure that it wasn't something I was doing wrong on my end.
v
I'm not sure, but as I said, report to JetBrains and see what they say. 🤷‍♂️ If it works when executing, it should work in IDE and if it does not, it is a bug in the IDE.
Also, IDE is by far not the only reason to use Kotlin instead of Groovy. You get error message much earlier as it already fails at compilation not only at execution and only if that part is actually executed. And in many situations with Groovy DSL you will get an error that - if you are able to interpret it correctly at all - will just tell you "somewhere in these 500 lines in that closure is some syntax error" and there is no chance to know where you can only randomly comment out things to find the syntax error.
But hey, to everyone their preferred way. 🙂
l
👍 I'll see if I can find where to ask IntelliJ people. With how finnicky gradle is, i've just gotten in the habit of editing like 3 lines of the buildscript between teach test run. So I know where the issues are. I've spent months of my life fighting with gradle. I really don't want to spend more learning kotlin just to fight in another language. (yes i know i'm a cranky old man) I'll have to dig around, if I can get syntax/intellisense for kotlin in eclipse I may give it another go. Just really don't like fighting the tools that are meant to help.
v
l
Do they have a slack/forum? I'd rather not file a bug report for something that very may well be user error.
v
Yes, at https://intellij-support.jetbrains.com/ you also find a forum. But as I said, if it works but is shown red in the IDE, ... 🤷‍♂️