Class ModuleScanDiagnostics
ComponentScanner and PluginManager both catch ClassNotFoundException |
LinkageError per class during a module's scan and skip-and-continue — the module still loads,
every other command still registers, and the one stale command silently does not exist. This
class does not change that shape; it only makes it loud. Its API is deliberately small: recordSkippedClass(String, String, Throwable) accumulates one skipped class for the module
currently being scanned, and emitSummary(String) — called once, after that module's
scan loop finishes — turns the accumulated list into exactly ONE Level.SEVERE record
naming the module, every skipped class, and pointing at COMPATIBILITY.md. A module that
skips nothing never calls the emitter at all, so a healthy startup produces no output from this
class whatsoever.
Never routes through the root logger. DIAGNOSTICS_LOGGER disables parent
handlers, exactly as RemoteActionLog does and for the same measured reason:
SystemLogHandler attaches only to the root (empty-name) logger and
auto-reports any Level.SEVERE record carrying a Throwable into
ErrorReportCollector — which would turn this per-module summary into an error report
and risk the circular logging both classes' javadoc already warns about. The summary emitted by
emitSummary(String) deliberately carries no Throwable for the same reason; the
individual causes live only on the per-class Level.FINE detail recorded by recordSkippedClass(String, String, Throwable). Disabling parent handlers also disconnects this
logger from the console/logs/latest.log sink the server installs on the root logger, so
a dedicated ConsoleHandler is attached directly — see the static initializer below and
07-JAPICMP-BASELINE.md's "D-19 diagnostic observation" section for the real-server
confirmation that this line reaches logs/latest.log.
- Since:
- 6.3.0
-
Field Summary
FieldsModifier and TypeFieldDescriptionprivate static final LoggerOne accumulator entry per module currently being scanned; cleared as each is emitted. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionstatic voidemitSummary(String moduleName) Emits ONELevel.SEVEREsummary formoduleNameif, and only if, at least one class was recorded for it since the last call — then resets the accumulator for that module, so a subsequent, cleanly-skip-free re-scan of the same module never repeats it.private static booleanstatic voidrecordSkippedClass(String moduleName, String className, Throwable cause) Records one class that failed to load duringmoduleName's scan, and immediately logs the per-class detail atLevel.FINEwithcauseattached — matching the shape the GEN-07 audit evaluator (D-14) also uses, so the two diagnostics read as one pattern.
-
Field Details
-
DIAGNOSTICS_LOGGER
-
SKIPPED_CLASSES_BY_MODULE
One accumulator entry per module currently being scanned; cleared as each is emitted.
-
-
Constructor Details
-
ModuleScanDiagnostics
private ModuleScanDiagnostics()
-
-
Method Details
-
recordSkippedClass
Records one class that failed to load duringmoduleName's scan, and immediately logs the per-class detail atLevel.FINEwithcauseattached — matching the shape the GEN-07 audit evaluator (D-14) also uses, so the two diagnostics read as one pattern.A
nullor blankmoduleNameorclassNameis ignored entirely — neither the accumulator nor the FINE detail record it — rather than producing a summary entry reading the literal text"null".- Parameters:
moduleName- the module (or, fromComponentScanner, the base package) whose scan is in progressclassName- the class that failed to loadcause- the exception the scan caught; may benull
-
emitSummary
Emits ONELevel.SEVEREsummary formoduleNameif, and only if, at least one class was recorded for it since the last call — then resets the accumulator for that module, so a subsequent, cleanly-skip-free re-scan of the same module never repeats it. A module with nothing recorded is a silent no-op: the emitter is never invoked at all.- Parameters:
moduleName- the module whose scan just finished
-
isBlank
-