Repository navigation
Enable the javac -Xlint categories that Error Prone cannot see - #67
Conversation
`HelmTest` uses the static, non-deprecated `Serialization.unmarshal` with
a Jackson `TypeReference`, so the `KubernetesSerialization` constant and
two `@SuppressWarnings("unchecked")` go away.
`ClusterConnectionReconcilerErrorTest` uses the reified `mock()` of
Mockito 5, which needs no suppression and no temporary variable.
8efda4d to
e0a353f
Compare
…sion, add README lead sentence Lombok added lombok.checkReturnValueAnnotation in 1.18.48, so the new lombok.config line had no effect on 1.18.46. The checkstyle version entry had no remaining reference. The README Setup heading lost its lead sentence when the registry section was removed.
stplasim
left a comment
There was a problem hiding this comment.
Just one thing, the HelmTest fix swaps one deprecated API for another. Rest looks good to me
…est` Assisted-by: Claude:claude-opus-5-5
@stplasim Good catch, thanks. Fixed in f982915. The static It slipped through because |
…javac-lint-categories-and-fix-deprecations
stplasim
left a comment
There was a problem hiding this comment.
LGTM
Nit: the PR description still says the deprecated calls were replaced by the static Serialization.unmarshal(...), and it says “4 warnings fixed” while listing 5.
On -Werror: this PR shows how easily a warning gets missed.
Assisted-by: Claude:claude-opus-5-5
Error Prone covers these categories only in part. A probe showed javac warnings with no Error Prone counterpart, for example an unreferenced try-with-resources variable or a redundant @SafeVarargs. Assisted-by: Claude:claude-opus-5-5
Follow-up to the Checkstyle removal #66
Error Prone reads the typed javac AST, so it cannot see everything the compiler sees.
This PR turns on the 17 lint categories that javac checks and Error Prone does not fully cover, fixes the 5 warnings they surfaced, and adds
-Werror.The build now compiles with 0 warnings and 0 notes, and
-Werrorkeeps it there.Why
Error Prone and
javaclint look at different things:The 90 Error Prone checks cover the AST side well. This PR closes the other side.
It deliberately does not enable a category that an Error Prone check fully owns, so no problem is reported twice.
Where Error Prone fully covers a rule, Error Prone wins: it has per-check severity, so a rule fails the build on its own. A javac lint category can only warn, so this PR adds
-Werror.The 17 enabled categories
Code quality (14)
deprecationremovaluncheckedcastrawtypesdivzerothis-escapeidentitysynchronizationis now a deprecated alias. Error Prone'sValueClassIdentity(ERROR) coverssynchronizedand more, but javac alone sees a value-based argument to a@RequiresIdentityparameter, such asnew WeakReference<>(Integer.valueOf(1))orCleaner.register(...), and a value-based type argument in a declaration, such asWeakHashMap<Integer, String>overloadsFunctionalInterfaceClashreportsConsumer<String>againstFunction<String, String>, but notConsumer<String>againstIntConsumer. javac reports bothvarargs@SafeVarargson a reifiable varargs type, and an unsafe use of the varargs array in a@SafeVarargsmethod. No Error Prone counterpart existstryclose()on a try-with-resources resource, a resource that the body never references, and a resource whoseclose()can throwInterruptedException. No Error Prone counterpart existstext-blocksdangling-doc-comments///markdown commentsrestrictedMemorySegment.reinterpret,System.loadandSystem.loadLibrary. Zero use today, so this is pure insuranceBuild hygiene (3)
options--releaseor source/target pairpathoutput-file-clashThe categories left off, and why
A. Error Prone fully owns it - 8 categories
Enabling these in javac would report the same problem twice, and at a lower severity. Every Error Prone check below runs at ERROR.
Each row was verified with a probe. The 11 categories of the former section A have 17 javac warning keys in the JDK 25
CompilerProperties, and the probe triggered 16 of them, with the categories and Error Prone enabled together. For the 8 categories below, every javac warning had an Error Prone error on the same construct. The key that was not probed isstatic.not.qualified.by.type2, a static member of an anonymous class accessed through an expression.emptyEmptyIfdep-annDepAnn@deprecatedin a///Markdown commentfallthroughFallThroughfinallyFinallylossy-conversionsNarrowingCompoundAssignmentbyteVar += 1overridesOverrides,EqualsHashCodeequalswithouthashCodestaticStaticQualifiedUsingExpressionauxiliaryclassMultipleTopLevelClasses,ClassNameThere is also a severity argument. javac has no per-category severity: a lint category can only warn unless
-Werrorpromotes every warning at once. An Error Prone check fails the build on its own.overloads,varargsandtrywere in this section before. The probe showed javac warnings with no Error Prone counterpart, so they moved to the enabled list. All three report 0 warnings on the codebase.Verification of
overloads,varargsandtryA second probe compiled the same constructs with
-XepAllDisabledChecksAsWarnings, so every Error Prone 2.51.0 check ran, also the ones that are off by default.TraditionalJavadocToMarkdownhad to stay off, because it crashes onDatabaseSpec(see #69).overloads: potentially ambiguous overloadConsumer<String>/Function<String, String>FunctionalInterfaceClashreports it toooverloads: potentially ambiguous overloadConsumer<String>/IntConsumer, static and instanceSupplier<String>/Callable<String>FunctionalInterfaceClashreports it, javac does notvarargs: redundant@SafeVarargs@SafeVarargsonString...varargs: unsafe use of the varargs parameter@SafeVarargs <T> void m(List<T>... a)storesain a fieldtry: explicitclose()on a resourcein.close()inside the try blocktry: resource never referencedinUnusedVariableskips resources on purposetry: resource never referencedunusedUnnamedVariablereports it, but only because of the name: its flagOnlyRenameVariablesNamedUnuseddefaults to truetry:close()can throwInterruptedExceptionAutoCloseablewhoseclose()declares itInterruptedExceptionSwallowedreported the enclosing method only because it declaresthrows ExceptionThe source of Error Prone 2.51.0 agrees: no check reads
@SafeVarargs, and the only checks that look at try-with-resources resources areTryWithResourcesVariable,UnnamedVariableandClosingStandardOutputStreams.So
FunctionalInterfaceClashand javacoverloadsoverlap in part, and each one reports a case that the other does not. Both stay on.B. Third-party noise - 3 categories
classfilemicroprofile-config-api-3.1.jar(35) andmicroprofile-health-api-4.0.1.jar(2). They reference OSGi annotations -org.osgi.annotation.bundle.Requirement,Requirements,versioning.Version- that are not on the compile classpath. Not our code, not fixable here.serialGrant,Role,Schema,Database,DefaultPrivilege,ClusterConnection. They inheritSerializablefrom the fabric8CustomResource, but they travel as JSON and are never Java-serialized. AserialVersionUIDon each would be pure ceremonyprocessingC. Not applicable - 8 categories
module,exports,opens,requires-automatic,requires-transitive-automaticandmissing-explicit-ctorall need a named module.The project has no
module-info.java.incubatingneeds an incubator module, andpreviewneeds a preview language feature.Neither is used, and
previewis on by default anyway.D. Deliberate aliases and near-misses
synchronizationis not listed.It is a deprecated alias of
identitysince JDK 25, and the toolchain's own--help-lintsays so.identityis listed instead.strictfpis not listed.It flags an unnecessary
strictfpmodifier, but all floating-point has been strict since Java 17, so the modifier has been meaningless for four releases.For it to fire, somebody would have to type a keyword that does nothing, in a codebase with zero
floatanddoubledeclarations.It is harmless to add and guards a mistake nobody here can make.
The 5 warnings that were fixed
removal- 1GrantReconcilerTest:SQLDataType.BIGINT.identity(true)→generatedByDefaultAsIdentity().The jOOQ method is deprecated and marked for removal.
Worth noting for a reviewer:
removalis on by default, so this warning was already visible before this PR. Nobody had looked.deprecation- 3HelmTest:Serialization.yamlMapper()twice andSerialization.jsonMapper()once, replaced byunmarshal(...)on the client'sKubernetesSerializationinstance (kubernetesClient.getKubernetesSerialization()), which is not deprecated. The two YAML reads pass a JacksonTypeReference, so their two@SuppressWarnings("unchecked")are gone as well.Reading also moves from
FiletoFiles.newInputStream. fabric8 closes the stream itself:unmarshal(InputStream, TypeReference)wraps it in try-with-resources, and theClassoverload calls that method.unchecked- 1ClusterConnectionReconcilerErrorTest: the mock creation carried//noinspection unchecked, an IntelliJ-only comment that javac ignores.It now uses the reified
mock()of Mockito 5, which infers the generic type from the assignment target, so no suppression is needed at all.Review notes
removalis redundant today, the same way two Error Prone entries are. javac enables it by default. It is listed so the intent is explicit and survives a JDK that changes the default.-Werroris on. The build is at zero warnings, so the ratchet holds today. javac promotes every warning: a deprecation that arrives with the next jOOQ or fabric8 bump fails the build, and so does any Error Prone check left at its default WARNING.-Werror, a javac lint warning hides the Error Prone findings of the same compilation. javac counts the warning as an error and stops before Error Prone runs. Error Prone reports its findings in the next build, after the javac warning is fixed.-Xlintlist because a check inerrorprone.argsfully covers them. The enabled categories overlap only in part:identitywithValueClassIdentityonsynchronized, andoverloadswithFunctionalInterfaceClashon same-arity functional interfaces. There, both tools report the same construct.Test scope
./gradlew --rerun-tasks :operator:compileJava :operator:compileTestJava :generated:compileJava- BUILD SUCCESSFUL, 0 warnings, 0 notes.-Xlint:allon the JDK 25 Amazon Corretto toolchain across all three source sets, with the warning cap raised so nothing was truncated. The category list came from that toolchain's ownjavac --help-lint, not from documentation.-Werrorwas proven live: a temporaryThread.getId()call failed the build with[deprecation], and a temporarya || b && cfailed it with Error Prone's[OperatorPrecedence], a check at its default WARNING.