Possible build improvement related to ConfigurationMetadataGenerator

28 views
Skip to first unread message

David Carr

unread,
Sep 27, 2021, 9:36:58 AM9/27/21
to CAS Community
I was recently doing some analysis on ways to improve the build times for the project, and noticed that :api:cas-server-core-api-configuration-model:generateConfigurationMetadata doesn't currently appear to be structured in a way that supports either UP-TO-DATE checks or build caching.  If we could address this, it might shave a good 8-10 seconds off of each build.

This task is currently a JavaExec to execute a custom class (ConfigurationMetadataGenerator).  It looks like that class reads in a JSON file generated at compile-time by Spring annotation processors, does some project analysis, and writes out an updated version of that same JSON file.  I don't see anywhere else in the project where that class is used, and it seems like the sort of thing that would be unlikely to be used outside the build for other purposes.

Gradle currently excludes this task from UP-TO-DATE checks because it doesn't declare any outputs.  We could use the DSL to declare outputs, but then we'd have issues because we're reading and writing the same file, and the outputs of the task would overlap with the outputs of the javaCompile task.  When I've encountered situations like this in the past, the approach I've taken has been to handle the compilation post-processing as an additional action for the javaCompile task, rather than a separate task.  With this approach, we can declare additional inputs for the javaCompile task as needed, and Gradle will consider the final outputs (after all actions have completed) for UP-TO-DATE and build caching.

For comparison, here's an example of that technique being used for bytecode enhancement in the Hibernate project.


While it's possible to use an anonymous closure to do this, it's recommended to instead use a named class for the action, as anonymous closures sometimes cause problems with caching due to ending up with different hash keys when compiled on different JDKs/OSs/etc.

If this all makes sense to others, I propose to assemble a pull request that:

* Removes :api:cas-server-core-api-configuration-model:generateConfigurationMetadata
* Converts ConfigurationMetadataGenerator from a command-line application to a Gradle Action (possibly in buildSrc), ConfigurationMetadataGeneratorAction
* Adds a doLast action for ConfigurationMetadataGenerator to :api:cas-server-core-api-configuration-model:javaCompile
* In my testing of the pull request, verify that UP-TO-DATE and build caching of :api:cas-server-core-api-configuration-model:javaCompile still works and that the content of the final json file is as expected

If anyone has input on these points, it would be helpful:

* Is it safe to remove ConfigurationMetadataGenerator (replacing it with a Gradle Action that can't be called outside the build) or do we need to maintain it (and possibly extract the logic so it can be used in multiple ways?
* Is there a reason that the JSON file is being written to multiple locations (both "${buildDir/<FILENAME>" and "${buildDir}/classes/java/main/META-INF/<FILENAME>"?  If so, why?  If one is not needed, can it be removed?

David Carr

unread,
Sep 27, 2021, 10:26:17 AM9/27/21
to CAS Community
This issue was discovered using Gradle Enterprise.

Here's an example Build Scan™ demonstrating the behavior.


To produce this, I first ran

./gradlew clean :api:cas-server-core-api-configuration-model:build -x test -x javadoc -x check

and then, without changing any source, ran:

./gradlew :api:cas-server-core-api-configuration-model:build -x test -x javadoc -x check --scan 

In the timeline view, you can see that the generateConfigurationMetadata task had status SUCCESS rather than UP-TO-DATE, and the cause in the details pop-up.
Reply all
Reply to author
Forward
0 new messages