Composite + Multiproject Cyclic AssetBuilder


(Julia) #1

I have a little bit of a chicken/egg scenario I’d like some insight on. I’ve done a lot of experiments and nothing seems to be working (I won’t detail all of them here unless it becomes necessary).

Suffice to say, I’ve got a multi-project as an included build in a composite which can be “simplified” to something like this:
Root-Composite
|
|__Root-library-multiproject
| |_____________jvm-subproject
| |______________buildAssets task (processResources depends on this)
|
|__Root-downsteam-app-multiproject
|_____________jvm-subproject
| |______________buildAssets task (processResources depends on this)
|
|__buildutils (also included build)

The idea is to use some code to call into a texture packer that is a module/sub-project in the library multiproject for all buildAssets tasks. I’ve put the calling code into the buildutils included build (with a build dependency on the submodules needed in the library included build) and by the time say, the library is ready to process resources, it /should/ be able to pull the onto a classpath for a javaexec task I think?

Originally I tried including the main and calling code in buildutils (included build side-by-side with the two other included builds), get this code on my buildscript classpath, and use it there, but for other reasons/probably user errors, I can’t get it to resolve at all.

The solution I have right now is, via cross-configuration inside these two included builds (library and downstream app), I create a buildutils configuration and then declare a buildutils dependency on the buildutils included build.

It was working this morning, entering into the buildutils included build main and throwing the exception I put there to confirm it. Then, suddenly it started throwing exceptions about not being able to see main it should be finding in the buildutils configuration, when I had made no changes to buildutils included-build nor to the javaexec main class declaration that pertain to classpath.

My only thought is that I’m kind of doing something totally unsupported, and maybe it only worked before bc of some caching at some level/layer?

I’m trying to work through the usual culprits right now (is buildutils included build module being substituted with the project correctly? though I think given the results I can already rule that out).

If there’s a better way to solve this issue in terms of approach, I’m all ears.

Also, I’m not sure if this is corruption or something, but around the same time I started experiencing some strange stuff in my composite root settings file. In there, if there isn’t a property declared via gradle properties chain (val SOME_PROP: String? by settings), my code will throw an exception. I commented out the only thing that could be providing this prop (declared in gradle.properties), and it still executed without throwing the exception. Not sure if gradle.properties are cached in some way? I’m using Intellij IDEA Ultimate.

I am currently on gradle-4.10-rc-3-all (Kotlin-DSL 1.0 RC3), Kotlin plugin in IDE is 1.2.61-release-IJ2018.2-1


(Julia) #2

I’m honestly not sure why this was even working before. I didn’t have a dependsOn(buildutils) declaration on the buildAssets task, simply a classpath = buildutils. When I add a dependsOn(buildutils) declaration for the buildAssets task, as expected, gradle detects a cyclic dependency at a (included) build level.

My last ditch hope before massive refactoring (which may not be possible right now) is to include the calling code in buildutils as a subproject in every included build that needs it to build assets so I can expose more granular dependencies for gradle, but I’m concerned about this when it comes to caching, parallel, etc, as I don’t know how it would affect things. Presumably each included build is isolated, but there are file locks, etc, and if they are both pointing toward the same project on disk, that’s where my concern comes in. Let alone it being kind of gross.


(Julia) #3

I confirmed it was indeed because I had built the build-utils build before adding all the dependency stuff (that’s why it worked that one time). Obviously, after a fresh clean, there would be no buildutils available and it wouldn’t be able to build because buildAssets in modules it depends on earlier in the chain don’t work.

I decided to move buildutils back into the multiproject in which it has modules that it depends on (as a subproject) and will allow composite dependency substitution to take care of substitution at the composite level for the build that buildutils does not depend on (but it still requires buildutils to build assets, the consuming app build).

My issue now is trying to get buildutils subproject to be able to build /before/ the library finishes assembling its jar (basically before processResources but after the classes have been built for the library). My thought is to have a dependency on the library modules’ classes directly instead of their jars for the buildutils subproject, but I’m unclear on how to do that and have just kept them as project dependencies for now. :frowning:

Anyone have any thoughts on how to do this? If gradle is capable?


(Julia) #4

I’ve decided to abandon having the library pack its own assets because of this scenario! Still, used lessons learned to have the app build use a buildutils config built off of the buildutils subproject module in the library build. :slight_smile:


(Stefan Oehme) #5

I recommend posting small example projects instead of long prose. It’s very hard to understand what the problem is, which is probably why no one suggested any solutions here.

Ideally you create a small github repo so people can send you solutions as a pull request.


(Julia) #6

I considered that and thank you for the advice, but the setup is actually very complex. I was pretty sure my error was more in something dumb and small in the task definition, but I included the other stuff for context. I should probably leave out the context initially since I already don’t think it’s pertinent.


(Stefan Oehme) #7

I’m sure you can boil the above down to a small sample. You don’t need any of your actual tasks and source files, just the barebones project structure and some dummy tasks that assert that some dummy class is on the classpath as you would hope.

From the description above it’s really not clear what you have been trying.


(Julia) #8

I decided to move away from this because it was creating a cyclic dependency in a composite build and was not critical to the project. AKA, this is now moot.