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? |
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