The controller was a static singleton: an eagerly created static instance
opened the root database during class initialization, and both the connection
and the path were static fields. A second operator profile in the same process
was therefore impossible, and ChatController's own "new DBController()" never
opened anything - it silently adopted the eagerly opened root connection.
- drop the eager static instance in favour of a lazily created default instance
- turn connection and path into instance state
- add a constructor taking a database file name relative to the application
directory plus a flag whether a missing file is seeded from the bundled
template
- create additional profile databases empty instead of seeding them: the
bundled template carries 3452 foreign callsigns and user_version 0, which
would show a new operator foreign data and trigger the full callsign
normalization rebuild. The schema is created by the existing table setup.
- remember the shutdown hook so closeDBConnection can deregister it; otherwise
every profile switch would leave another hook holding a dead connection
All SQL statements keep referencing the plain field and are unchanged.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Hpa6bjie5qkeNG62y6FmXm
Record redacted RX/TX frames with session rotation and runtime debug controls.
Add targeted file diagnostics, tests, documentation, and a silent priority-score refresh path.
The ON4KST connection manager introduced in f8c04e7 uses
jdk.net.ExtendedSocketOptions to configure kernel side TCP keepalives. The
new dependency was added to module-info.java and to the jpackage Maven
plugin, but the CI and AUR builds do not use that plugin: they call jpackage
directly with a hardcoded --add-modules list that still lacked jdk.net.
Because jdk.net is not pulled in transitively, every packaged runtime image
shipped without the class while development runs against the full JDK and
kept working.
The resulting NoClassDefFoundError is an Error, so neither the catch in
configureSocket nor the surrounding catch (Exception) in openConnection
handled it. Running on a ScheduledExecutorService, the throwable was stored
in the task future and never surfaced, leaving the state machine stuck in
CONNECTING with no reconnect attempt and no user visible failure.
Add jdk.net to all 16 module lists, covering nightly artifacts, tagged
releases and both AUR PKGBUILDs, so releases are affected as well as
nightlies. Additionally catch LinkageError in configureSocket so a runtime
image without jdk.net degrades to application level heartbeats, and catch
Throwable in openConnection so an Error can no longer be swallowed by the
scheduler.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Session-based ON4KST connection lifecycle: Each socket, reader, writer, message bus and queue now belongs to an explicitly identified connection session. Delayed threads from an obsolete connection can therefore no longer process data or close its replacement. ONLINE is reported only after the login has been accepted and all requested user lists have been received. Connection setup, login and synchronisation use bounded timeouts, while heartbeats, missing inbound traffic, EOF and read or write failures trigger controlled reconnect attempts with backoff where appropriate.
Validated ON4KST protocol commands: Outgoing frames are built centrally and checked for valid categories, locators and prohibited frame delimiters. Because ON4KST maintains one locator per TCP session, the main locator is used for both chat categories and a conflicting secondary configuration is logged instead of sending contradictory commands to the server.