Skip to content

[main] Warn when @PluginBuilderAttribute field lacks public setter (#3195 port)#4156

Open
vpelikh wants to merge 3 commits into
apache:mainfrom
vpelikh:port-3195-annotation-processor-setter-warning
Open

[main] Warn when @PluginBuilderAttribute field lacks public setter (#3195 port)#4156
vpelikh wants to merge 3 commits into
apache:mainfrom
vpelikh:port-3195-annotation-processor-setter-warning

Conversation

@vpelikh

@vpelikh vpelikh commented Jun 26, 2026

Copy link
Copy Markdown

This ports the annotation processor validation from #3195 (2.x) to main (3.x).

What it does

The PluginProcessor annotation processor now validates that every @PluginBuilderAttribute field in a plugin builder class has a public setXxx() or withXxx() method that:

  1. Takes exactly 1 parameter matching the field type
  2. Returns a type assignable to the enclosing builder class
  3. Is declared public

If no such setter is found, a compilation ERROR is emitted:

The field `myField` does not have a public setter. Note that
@SuppressWarnings("log4j.public.setter") can be used on the field to
suppress the compilation error.

Suppressing false positives

Use @SuppressWarnings("log4j.public.setter") on the field to suppress the warning for legitimate cases (e.g., fields set via constructor or reflection).

Files changed

  • PluginProcessor.java — Added setter validation logic in processBuilderAttributeFields()
  • PluginProcessorPublicSetterTest.java — Test with 3 cases: public setter OK, missing setter → error, suppressed → no error
  • FakePluginPublicSetter.java.source — Test plugin for the above test
  • SocketPerformancePreferences.java — Added @SuppressWarnings to 3 fields (setters return void, not builder type)
  • StringMatchFilter.java — Added @SuppressWarnings (setMatchString name doesn't match field text)
  • Rfc5424Layout.java — Added @SuppressWarnings (field enterpriseNumber has no setter)

Note

Unlike the 2.x version, the 3.x PluginProcessor uses @SupportedAnnotationTypes({"org.apache.logging.log4j.plugins.Plugin", "org.apache.logging.log4j.plugins.PluginBuilderAttribute", "org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute"}) and iterates by FQN, because 3.x has two @PluginBuilderAttribute variants.

The annotation processor now validates that every @PluginBuilderAttributevfield in a plugin builder class has an accessible public setter method (setXxx or withXxx). If no setter is found, a compilation ERROR is emitted.

Use @SuppressWarnings("log4j.public.setter") on the field to suppress.

Added @SuppressWarnings to known false positives in:
- SocketPerformancePreferences (3 fields: setters return void, not builder)
- StringMatchFilter (field 'text' has setter named 'setMatchString')
- Rfc5424Layout (field 'enterpriseNumber' has no setter at all)

Signed-off-by: Vasily Pelikh <2010720+vpelikh@users.noreply.github.com>
@vpelikh vpelikh changed the title Warn when @PluginBuilderAttribute field lacks public setter (#3195 port) [main] Warn when @PluginBuilderAttribute field lacks public setter (#3195 port) Jun 26, 2026
@vpelikh vpelikh mentioned this pull request Jun 26, 2026
27 tasks
@ramanathan1504

Copy link
Copy Markdown
Contributor

@vpelikh

However, your new processor works so well that it actually caught a pre-existing violation in main! When building locally, the compile fails in log4j-jdbc because JdbcAppender is missing public setters:

[ERROR] .../log4j/jdbc/appender/JdbcAppender.java:[61,25] The field immediateFail does not have a public setter.
[ERROR] .../log4j/jdbc/appender/JdbcAppender.java:[81,22] The field reconnectIntervalMillis does not have a public setter.

Could you please update JdbcAppender.java in this PR (either by adding the missing setters or suppressing the warning) so the CI builds successfully? Once the build is green, I'll happily approve and merge!

@ramanathan1504

Copy link
Copy Markdown
Contributor

@vpelikh, Also, I noticed Spotless formatting on 3 PR as well. When you push your updates, please make sure to run ./mvnw spotless:apply Follow the BUILDING.adoc

vpelikh added 2 commits July 16, 2026 15:10
The annotation processor requires @PluginBuilderAttribute setters to return a type assignable to the enclosing builder class. Changed setImmediateFail() and setReconnectIntervalMillis() from void to B, following the same pattern as all other setters in the Builder class.

Fixes compilation errors caught by the new annotation processor validation:
- The field immediateFail does not have a public setter.
- The field reconnectIntervalMillis does not have a public setter.

Signed-off-by: Vasily Pelikh <2010720+vpelikh@users.noreply.github.com>
Fixes formatting violations caught by spotless:check:
- PluginProcessor: line wrapping, duplicate import removal
- PluginProcessorPublicSetterTest: line wrapping consistency

Signed-off-by: Vasily Pelikh <2010720+vpelikh@users.noreply.github.com>
@vpelikh
vpelikh force-pushed the port-3195-annotation-processor-setter-warning branch from 552a04f to a38185a Compare July 16, 2026 12:10
@vpelikh

vpelikh commented Jul 16, 2026

Copy link
Copy Markdown
Author

Thank you for the review, @ramanathan1504 ! Great catch – you're absolutely right, the new validation uncovered real issues in JdbcAppender.

I've just pushed two commits that:

  1. Fix the setter return types – changed setImmediateFail() and setReconnectIntervalMillis() from void to B (the builder type), so they now satisfy the annotation processor's requirements.
  2. Apply Spotless formatting – ran ./mvnw spotless:apply to fix all formatting violations across the affected files.

The build should be green now. Please take another look when you have a moment – happy to adjust anything else if needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Development

Successfully merging this pull request may close these issues.

2 participants