Preserve property descriptions during Gradle incremental compilation - #50489
Preserve property descriptions during Gradle incremental compilation#50489galenzo17 wants to merge 1 commit into
Conversation
Cache descriptions in a location outside CLASS_OUTPUT so that Gradle's incremental compilation does not lose javadoc-based descriptions for types passed as .class files. See spring-projectsgh-28075 Signed-off-by: Agustin Bereciartua <bereciartua.agustin@gmail.com>
9a177ef to
3baf552
Compare
|
Thanks for the PR. I am wondering why we wouldn't be able to re-read the generated metadata rather than storing things in a gradle specific location. This would also be a annotation processor only change that, if the Javadoc is not available, then take the value from the previous round. |
Gradle deletes the previously generated metadata before incremental compilation begins. |
|
Thanks both! I tried reading the previous metadata too, but Gradle clears it before the incremental build starts, so there's nothing left to read. That's why I went with the cache. Happy to take a different approach if you'd prefer one — otherwise, would it help if I put together some benchmarks to back this up? |
|
Hi @snicoll @wilkinsona — friendly ping now that this area is getting attention. Given Gradle deletes the previous metadata before the incremental round, is the cache approach acceptable in principle? If yes, I'll mark this ready and add the Gradle-plugin wiring for descriptionCacheLocation; if you'd rather see a different approach, just point me at it and I'll rework. |
|
Thanks, @galenzo17, and thanks for your patience. We've managed to make some inroads into the PR backlog and hope to be able to give this PR the time that it deserves in the not too distant future. |
Status
Draft. Seeking approach validation before adding performance benchmarks
and a repro on a spring-boot-internal module. Specifically requesting
sanity-check on the
FieldValuesParserextension (the@FunctionalInterfaceremoval to add a default method).
Summary
When Gradle performs incremental compilation, unchanged
@ConfigurationPropertiesclasses are passed to the annotation processor as
.classfiles via theclassesparameter of
JavaCompiler.getTask(). Since bytecode does not carry javadoc,Elements.getDocComment()returnsnullfor these elements and their propertydescriptions are lost from
spring-configuration-metadata.json.This implements option 1 from the issue thread
(confirmed by @wilkinsona):
cache descriptions in a location outside
CLASS_OUTPUTthat Gradle does not cleanduring incremental builds.
Approach
org.springframework.boot.configurationprocessor.descriptionCacheLocationconfigures where the cache file lives (opt-in, zero behavior change when unset)
.class-backed elements are detected viacom.sun.source.util.Trees.getTree(),reusing the existing reflection wrapper in
JavaCompilerFieldValuesParser.class-backed types are filled from cache before theJSON is emitted; then the cache is replaced with the current metadata
automatically pruned — no unbounded growth
Files changed
FieldValuesParserdefault hasSourceTree()(removed@FunctionalInterface— internal API)JavaCompilerFieldValuesParserhasSourceTree()using existingTreesinstanceMetadataGenerationEnvironmenthasSourceTree()delegating to field values parserConfigurationMetadataAnnotationProcessor.class-backed types, fills missing descriptions from cache on write, then refreshes cacheDescriptionCache(new)DescriptionCacheTests(new)Tests
DescriptionCacheTests— all passspring-boot-configuration-processortests continue to passScope and limitations
spring-boot-gradle-pluginshould wire thedescriptionCacheLocationoption automaticallyAlternatives considered
ecosystem-wide migration of existing property descriptions from javadoc to a new
annotation
replace strategy is simpler and leverages the invariant that Gradle passes all
annotated types every round
See gh-28075