Environment: - Eclipse 2022-12 (4.26.0) - Java 17 - Spring Tools Suite (STS) 4 (4.17.2) - Spring Boot 3.0.4 - Lombok 1.18.26
Problem:
After saving a modified @ConfigurationProperties class, Eclipse is running the annotation processors lombok (at first!) and org.springframework.boot.configurationprocessor.ConfigurationMetadataAnnotationProcessor during its incremental update. My expectation is that the META-INF/spring-configuration-metadata.json is updated and the Spring Boot Language Server shows a updated code completion list in Eclipse. But in Spring Boot 3.0.4, no update is performed. A newly added or existing modified configuration property is marked as unknown in the application.yml (Eclipse Generic Editor - Spring YAML properties). In addition to that, Eclipse throws 2 exceptions when running the ConfigurationMetadataAnnotationProcessor.
eclipse-exception-1.txt
eclipse-exception-2.txt
Workaround:
My current workaround is to create an own class for the static inner class. The corresponding field in the @ConfigurationProperties class is annotated with @NestedConfigurationProperty. In this case, the META-INF/spring-configuration-metadata.json is updated as expected, no eclipse exceptions are thrown and the code completion works like a charm. As an alternative a full build (Alt + F5 in Eclipse for maven update) might be a workaround, too.
Steps to reproduce:
- Checkout this demo project
- Run a maven update in Eclipse (Alt + F5)
- Open the "Error Log" in Eclipse
- Open the java file
com.example.demo.inner.InnerDemoConfigurationPropertiesand add a new field or modify an existing one 3.1 Check the "Error Log" for the exceptions mentioned above in the attachments 3.2 Open the application.yml in src/main/resources and check the code completion and warnings for unknown properties
Comment From: philwebb
From the stack trace, it doesn't look like our annotation processor is doing anything wrong. I suspect this might be an Eclipse issue.
@gebinic Does the issue only occur when using Lombok?
Comment From: cpfeiffer
No, this also happens when removing the @Data annotation from InnerDemoConfigurationProperties and letting eclipse generate the getters and setters. Whenever you save the file, the exception occurs.
I suspect that the the qualified class name is either passed in a wrong format from the annotation processor to the apt environment (TypeUtils.java:237) or that jdt's apt environment handles it wrongly. Looking into jdt's source suggests that it doesn't find the inner class and thinks it has been renamed.
Comment From: wilkinsona
Thanks for the sample.
This looks like a JDT bug to me. I added some rudimentary debugging information to TypeUtils:
private void process(TypeDescriptor descriptor, TypeMirror type) {
if (type.getKind() == TypeKind.DECLARED) {
DeclaredType declaredType = (DeclaredType) type;
String elementName = this.types.asElement(type).toString();
this.env.getMessager().printMessage(Kind.NOTE, "Getting type element for '" + elementName + "'");
DeclaredType freshType = (DeclaredType) this.env.getElementUtils().getTypeElement(elementName).asType();
this.env.getMessager().printMessage(Kind.NOTE, "Got '" + freshType + "'");
List<? extends TypeMirror> arguments = declaredType.getTypeArguments();
for (int i = 0; i < arguments.size(); i++) {
TypeMirror specificType = arguments.get(i);
TypeMirror signatureType = freshType.getTypeArguments().get(i);
descriptor.registerIfNecessary(signatureType, specificType);
}
TypeElement element = (TypeElement) this.types.asElement(type);
process(descriptor, element.getSuperclass());
}
}
The info messages appear in Eclipse's error log. When performing a full build, the following is logged:
Getting type element for 'com.example.demo.inner.InnerDemoConfigurationProperties.Inner'
Got 'com.example.demo.inner.InnerDemoConfigurationProperties.Inner'
When I change InnerDemoConfigurationProperties and save it, the following is logged:
Getting type element for 'com.example.demo.inner.InnerDemoConfigurationProperties.Inner'
Exception thrown by Java annotation processor org.springframework.boot.configurationprocessor.ConfigurationMetadataAnnotationProcessor@7ed87ecd
Note that the name being passed into javax.lang.model.util.Elements.getTypeElement(CharSequence) is the same each time yet it fails during incremental compilation. Short of swallowing the exception, which I don't think we should do as it would result in incorrect metadata, I don't think there's anything we can do about it in Boot.
@cpfeiffer Can you please report this to the JDT maintainers?
Comment From: cpfeiffer
Done, thanks for the quick analysis!