Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix(#2769): Modify the annotation processor in 2.x to give a warning if a plugin builder attribute does not have a public setter. #3195

Open
wants to merge 2 commits into
base: 2.x
Choose a base branch
from

Conversation

jaykataria1111
Copy link

The following commit modifies the annotation processor in 2.x to shell out a warning if the plugin builder attribute does not have a public setter.

A @SuppressWarnings("log4j.public.setter") attribute can be used to ignore this compilation warning incase it is a known issue.

Checklist

  • Base your changes on 2.x branch if you are targeting Log4j 2; use main otherwise
  • ./mvnw verify succeeds (if it fails due to code formatting issues reported by Spotless, simply run ./mvnw spotless:apply and retry)
  • Non-trivial changes contain an entry file in the src/changelog/.2.x.x directory
  • Tests for the changes are provided
  • Commits are signed (optional, but highly recommended)

ppkarwasz and others added 2 commits November 9, 2024 01:50
This adds setters to `@PluginBuilderAttribute` fields in setter classes that lack the corresponding public setter.
… plugin builder attribute does not have a public setter.
@jaykataria1111 jaykataria1111 marked this pull request as ready for review November 9, 2024 11:15
@ppkarwasz ppkarwasz self-assigned this Nov 11, 2024
Copy link

Job Requested goals Build Tool Version Build Outcome Build Scan®
build-macos-latest clean install 3.9.8 Build Scan PUBLISHED
build-ubuntu-latest clean install 3.9.8 Build Scan PUBLISHED
build-windows-latest clean install 3.9.8 Build Scan PUBLISHED
Generated by gradle/develocity-actions

Copy link
Contributor

@ppkarwasz ppkarwasz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jaykataria1111,

Thanks for your contribution! I added some minor remarks below.

If you haven't done it already, please sign the ASF ICLA.

import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import org.junit.Test;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
import org.junit.Test;
import org.junit.jupiter.api.Test;

Please use JUnit 5. Our JUnit 4 tests are being currently rewritten to JUnit 5.

When using JUnit 5, the recommended style is to make all classes and methods package-private instead of public.

// Get the source files
Path sourceFile = Paths.get(FAKE_PLUGIN_CLASS_PATH);

assertThat(Files.exists(sourceFile)).isTrue();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
assertThat(Files.exists(sourceFile)).isTrue();
assertThat(sourceFile).exists();

}

@Test
public void IgnoreWarningWhenSuppressWarningsIsPresent() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public void IgnoreWarningWhenSuppressWarningsIsPresent() {
public void ignoreWarningWhenSuppressWarningsIsPresent() {

// Get the source files
Path sourceFile = Paths.get(FAKE_PLUGIN_CLASS_PATH);
System.out.println(FAKE_PLUGIN_CLASS_PATH);
assertThat(Files.exists(sourceFile)).isTrue();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
assertThat(Files.exists(sourceFile)).isTrue();
assertThat(sourceFile).exists();

Comment on lines +159 to +181
boolean followsNamePattern = methodName
.toLowerCase(Locale.ROOT)
.equals(String.format("set%s", fieldName.toLowerCase(Locale.ROOT)))
|| methodName
.toLowerCase(Locale.ROOT)
.equals(String.format("with%s", fieldName.toLowerCase(Locale.ROOT)));

if (fieldName.toLowerCase(Locale.ROOT).startsWith("is")) {
followsNamePattern = methodName
.toLowerCase(Locale.ROOT)
.equals(String.format(
"set%s",
fieldName
.toLowerCase(Locale.ROOT)
.substring(2)))
|| methodName
.toLowerCase(Locale.ROOT)
.equals(String.format(
"with%s",
fieldName
.toLowerCase(Locale.ROOT)
.substring(2)));
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we could be stricter here and use a case-sensitive comparison, for example add a helper method that:

  1. Removes an is prefix from the field name.
  2. Capitalizes the first letter.
  3. Compares with the method name with set or with removed.

processingEnv
.getMessager()
.printMessage(
Diagnostic.Kind.WARNING,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that ERROR would be fine here.

Just make sure that the message contains a mention about the @SuppressWarnings annotation, so third-party Log4j plugin developers don't get crazy if they can not create a setter.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants