ramanathan1504 commented on PR #4156:
URL: https://github.com/apache/logging-log4j2/pull/4156#issuecomment-5128109308

   Thanks for the quick turnaround @vpelikh. Both of my earlier points are 
confirmed fixed:
   
   **`JdbcAppender`** — I ran the full reactor build off your branch and all 27 
modules are green, with zero `does not have a public setter` diagnostics 
anywhere:
   
   ```
   [INFO] Apache Log4j JDBC ................................. SUCCESS
   [INFO] BUILD SUCCESS
   ```
   
   **Spotless** — `./mvnw spotless:check` is clean across the whole reactor.
   
   `PluginProcessorPublicSetterTest` passes 3/3, and the existing 
`PluginProcessorTest` / `GraalVmProcessorTest` still pass.
   
   So the blocking issues are gone. A few things came up while I was reading 
the port more closely.
   
   ---
   
   ### 1. The new test leaves generated files in the source tree
   
   This is the one I'd like fixed before merge. Running just the new test on a 
clean checkout:
   
   ```
   $ ./mvnw -pl log4j-plugin-processor -Dtest=PluginProcessorPublicSetterTest 
surefire:test
   $ git status --porcelain
   ?? log4j-plugin-processor/example/
   ?? 
log4j-plugin-processor/org.apache.logging.log4j.plugins.model.PluginService
   ```
   
   Those are the processor's real outputs (`example/plugins/Log4jPlugins.java` 
and the service registration), written relative to the working directory 
because the compilation task doesn't specify an output location.
   
   The cause is that `@AfterEach` cleans up `Log4j2Plugins.dat` — that's the 
**2.x** artifact name. `Log4j2Plugins` doesn't appear anywhere in the 3.x 
processor; 3.x generates a `Log4jPlugins` class plus a `META-INF/services` 
entry instead. So the cleanup was carried over verbatim from the 2.x test and 
deletes a file that is never created, while missing the two that are.
   
   Simplest fix is to give the compiler task an output directory under 
`@TempDir` (`-d` / `-s`) so nothing lands in the module directory at all. That 
would also let you drop the copy of `FakePluginPublicSetter.java.source` into 
`src/test/resources/` — writing a `.java` into the source tree and deleting it 
afterwards is a bit fragile if a test fails partway.
   
   ### 2. `@SupportedAnnotationTypes` diverges from 2.x more than it needs to
   
   The PR notes say the annotation-types list had to change "because 3.x has 
two `@PluginBuilderAttribute` variants". I don't think that follows. 2.x keeps 
`@SupportedAnnotationTypes` scoped to `Plugin` and resolves the attribute 
annotation inside `process()`:
   
   ```java
   final Set<? extends Element> pluginAttributeBuilderElements =
           
roundEnv.getElementsAnnotatedWith(elementUtils.getTypeElement(PLUGIN_BUILDER_ATTRIBUTE_ANNOTATION));
   processBuilderAttribute(pluginAttributeBuilderElements);
   ```
   
   Handling two variants there is just two `getTypeElement` lookups — it 
doesn't require adding them to `@SupportedAnnotationTypes` or restructuring 
`process()` into an FQN if/else chain.
   
   Two consequences of the current approach worth weighing:
   
   - The processor is now invoked in rounds where no `@Plugin` is present at 
all, so it validates `@PluginBuilderAttribute` fields in classes that aren't 
plugin builders. That's a wider net than 2.x casts. It may well be what you 
want, but it's a behavioural change from the code being ported and should be a 
deliberate call.
   - The two FQNs are hardcoded in the annotation list *and* again in the 
`process()` dispatch, while `internal/Annotations.java` already owns exactly 
these strings (`QUALIFIER_TYPE_NAMES` lists both `PluginBuilderAttribute` 
variants). That file also carries a note that its annotations "must also be 
declared in `GraalVmProcessor`" — there's an existing coupling here that the 
new code sidesteps rather than joins.
   
   Could you either follow the 2.x shape, or reuse `Annotations`?
   
   ### 3. You fixed a real 2.x bug — please say so (and test it)
   
   Worth calling out because it's a genuine improvement, not just a port. 2.x 
guards the loop with:
   
   ```java
   if (methodName.toLowerCase(Locale.ROOT).startsWith("set") && 
parameters.size() == 1)
   ```
   
   so the `withXxx` half of its `followsNamePattern` check is unreachable dead 
code — a `withFoo` setter would never satisfy 2.x's validator. Your version 
guards on `set` **or** `with`, which makes `withXxx` actually work.
   
   That's a good catch and should be mentioned in the PR description as an 
intentional deviation. It also deserves a test case — `FakePluginPublicSetter` 
currently only exercises `setXxx`.
   
   ### 4. Suppress vs. fix — and a collision with #4153
   
   Five pre-existing violations are silenced with `@SuppressWarnings`. I'd like 
a sentence on each, because the point of the check is to surface exactly these:
   
   - **`StringMatchFilter.text`** — suppressed because the setter is named 
`setMatchString`. This collides with #4153, which renames that setter to 
`setText`; once it lands the suppression is dead. The two PRs also touch 
adjacent lines of the same file, so whichever merges second will conflict. 
Let's agree an order — my preference is #4153 first, then drop the suppression 
here.
   - **`Rfc5424Layout.enterpriseNumber`** — no setter at all, and there's a 
sibling `ein` field. That smells like a genuine latent bug rather than a false 
positive. Can it be fixed instead of muted?
   - **`SocketPerformancePreferences`** (3 fields) — void setters, the same 
shape as the `JdbcAppender` ones you *fixed* by returning `B`. I suspect the 
difference is that this isn't a fluent builder (`newBuilder()` returns the 
class itself), which is a fine reason — just please state it, so the 
inconsistency doesn't read as arbitrary.
   
   ### 5. Should the severity be configurable?
   
   Not a defect in this PR, just a design question. 2.x routes every processor 
diagnostic through a helper gated by the 
`log4j.plugin.processor.minAllowedMessageKind` option, specifically so build 
environments can dial processor messages down. `main`'s `PluginProcessor` has 
never had that option, so you haven't removed anything — but this PR introduces 
the first hard `ERROR` that can break a downstream plugin author's compile, 
with only the per-field `@SuppressWarnings` as an escape hatch. Worth deciding 
whether the option should come across too, or whether `@SuppressWarnings` is 
considered sufficient.
   
   ### Minor
   
   - `javax.tools.Diagnostic.Kind.ERROR` is fully qualified, but 
`javax.tools.Diagnostic.Kind` is already imported and used as `Kind.NOTE` 
elsewhere in the same file.
   - `methodName.toLowerCase(Locale.ROOT).startsWith("set")` is redundant with 
the exact-equality `followsNamePattern` check right below it.
   - `expectedFieldNameInASetter` strips a leading `is` unconditionally. That's 
correct for `ColumnConfig`'s `isClob` / `isUnicode` / `isEventTimestamp`, which 
is presumably why it exists, but a field named e.g. `isolationLevel` would be 
told to add `setOlationLevel`. Inherited from 2.x, so not yours — a short 
comment would save the next reader.
   - The test class is `public class`; `PluginProcessorTest` next to it is 
package-private.
   - Test names say `warnWhen...` / `ignoreWarning...` / `noWarning...`, but 
the diagnostic is an `ERROR`.
   - `assertThat(errorDiagnostics).allMatch(x -> !...)` reads more directly as 
`noneMatch(...)`.
   - No coverage for the other two conditions in `foundPublicSetter`: a setter 
that exists but isn't `public`, and one whose return type isn't assignable to 
the builder.
   
   ### Changelog
   
   No entry needed here, and there isn't one — that's correct. Consistent with 
our other 2.x → `main` ports (#4152, #4154, #4157, #4128), none of which added 
one: the fix already has its entry on `2.x` and the behaviour has never shipped 
in a released 3.x.
   
   One thing to be conscious of: changing `setImmediateFail` / 
`setReconnectIntervalMillis` from `void` to `B` is a binary-incompatible 
signature change. Since 3.0.0 is unreleased nothing downstream can break, so 
I'm not asking for anything — just flagging it as a deliberate call rather than 
an accidental one.
   
   ---
   
   Item 1 is the only thing I'd consider blocking. Everything else is a 
question or a nit, and I'm happy to be talked out of any of them.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to