Skip to content

FontIcon NPE storm on stylesheet hot-swap (27-ea reset x Ikonli requireNonNull x CSSFX), amplified by per-exception alert dialogs #886

Description

@knowledge-graphlet

Symptom

Bursts of uncaught NullPointerException: Argument 'code' must not be null on the FX thread (org.kordamp.ikonli.javafx.FontIcon.setIconCode), each spawning a modal error dialog, dozens at a time (observed 2026-07-24 in a fast-dev komet-desktop session).

Diagnosis — four factors chained

  1. Trigger: CSSFX hot-swap. In dev mode CssUtils loads CSS from the source tree and starts CSSFX. Editing komet.css on disk while the app runs makes CSSFXMonitor$URIStyleUpdater swap the stylesheet URI → the scene's stylesheet list changes → full-tree reapplyCSS.
  2. JavaFX 27-ea reset. CssStyleHelper.createStyleHelper → resetToInitialValues resets every previously-CSS-styled styleable property to its initial value before the new stylesheet applies. This is the aggressive-reset behaviour of the CSS fix the komet-bom JavaFX pin (27-ea+24, JDK-8268657 — the CSS-corruption fix) deliberately retains; upstream backed it out in 27-ea+25, plausibly for this regression class.
  3. Ikonli rejects its own initial value. FontIcon's iconCode styleable has initial value null, but its invalidation listener calls setIconCode(n) which does requireNonNull — so the reset always throws. Unfixed upstream: ikonli master (and 12.4.0, latest) still has the unguarded listener. A styleable property that cannot accept its own CssMetaData initial value is an Ikonli spec violation worth reporting upstream.
  4. Amplification: the alert loop. komet.css alone carries ~94 -fx-icon-code rules — one NPE per styled icon per swap — and AlertDialogSubscriber.drainQueue shows a modal showAndWait dialog per exception; each dialog's nested event loop lets the queued CSSFX updates keep firing, so one stylesheet edit becomes a dialog storm.

Options

  1. Throttle/dedupe AlertDialogSubscriber — collapse repeated identical exceptions into one dialog (or log-only after N). Bounded, uncontroversial, fixes the storm whatever the source. Recommended now.
  2. Upstream Ikonli fix — guard the listener (if (n != null)) or accept null as "clear icon"; file/PR against kordamp/ikonli. The real root fix.
  3. CSSFX scoping — stop live-monitoring stylesheets that style FontIcons; costs the live-CSS loop dev workflow.
  4. Move the JavaFX ea pin — losing JDK-8268657 brings the CSS corruption back; not worth it.

Until one of these lands: expect a dialog burst whenever komet.css (or any watched stylesheet) is edited while a fast-dev app is running — including edits arriving via Syncthing from the other machine.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions