Network Chat is a Java 21 chat application over TCP sockets with:
- a resilient server with user handshake and broadcast.
- a console client.
- a bot client with date/time commands.
- a Swing GUI client with an embedded connection panel, retry/cancel flow, saved last settings, local message timeline, rooms, private messages, and MVC style structure.
- optional file-backed message history with room replay after server restart.
- optional TLS mode, token-based accounts with
USER/ADMINroles, and the admin/healthcommand. - a Windows release zip with launch scripts, checksums, and provenance metadata.
- reproducible Gradle build, tests, CI, and quality gates.
- Java 21+
./gradlew runServer --args="--port 1500"
./gradlew runClient
./gradlew runBotClient
./gradlew runGuiClientServer and clients can also be run directly with Java by building jars from Gradle.
The default server port is 1500. Programmatic server startup can use ChatServerConfig to set the
port, maximum client count, handshake timeout, and post-handshake read timeout.
To enable file-backed history:
./gradlew runServer --args="--port 1500 --history build/chat-history.jsonl"To enable accounts, first generate rows for accounts.csv:
./gradlew createAccount --args="alice USER secret" >> build/accounts.csv
./gradlew createAccount --args="admin ADMIN admin-secret" >> build/accounts.csv
./gradlew runServer --args="--port 1500 --accounts build/accounts.csv"Clients send the token through the GUI Token field or the NETWORK_CHAT_TOKEN environment
variable. Admin users can send /health and receive a private server status response.
To enable TLS, create a Java keystore for the server:
keytool -genkeypair -alias network-chat -keyalg RSA -keysize 3072 -validity 365 \
-keystore build/network-chat.p12 -storetype PKCS12 -storepass changeit
./gradlew runServer --args="--port 1500 --tls-keystore build/network-chat.p12 --tls-password changeit"Clients enable TLS through environment variables:
$env:NETWORK_CHAT_TLS="true"
$env:NETWORK_CHAT_TRUSTSTORE="build/network-chat.p12"
$env:NETWORK_CHAT_TRUSTSTORE_PASSWORD="changeit"
./gradlew runGuiClientTo build a no-Gradle release package for end users:
./gradlew releaseBundleArtifacts are written to build/release: the Windows zip, checksums.txt, and provenance.json.
The compact architecture contract is documented in docs/architecture.md.
ChatServeraccepts TCP connections and handles clients in a bounded executor.ChatConnectionreads and writes one-line UTF-8 JSON frames.ChatProtocolserializesChatMessage.ChatMessagecarriesprotocolVersion; unversioned clients receive an explicitERROR.- For
TEXTmessages,datacontains only raw text andsendercontains the author. TEXTmessages are broadcast to every client, including the sender, so users see their own sent messages in the timeline.ROOM_TEXTis delivered only to room members;PRIVATE_TEXTis delivered only to the sender and recipient.- The GUI keeps a bounded local timeline for the current session, renders
USER_ADDED/USER_REMOVEDas service events, usesmessageIdfor deduplication, and supports search by text, sender, date/timestamp, room, recipient plus JSON/CSV export. - When history is enabled, the server stores
ROOM_TEXT/PRIVATE_TEXTframes as JSONL, bounds the history size, migrates legacy unversionedTEXTrecords, and replays recent room messages on join. - When accounts are enabled, the server accepts only
USER_NAMEframes with a valid token; roles are used for admin-only commands. - TLS is enabled through server configuration and client environment variables.
- Console and Swing clients format display text such as
alice: hello. - The bot client reads date/time commands from
dataand uses the author fromsender.
src/main/java— core application classes.src/test/java— unit tests.src/integrationTest/java— protocol and network integration tests.src/uiTest/java— Swing smoke tests.docs— architecture notes and visual assets..github/workflows— CI, CodeQL and Scorecard workflows.
./gradlew test./gradlew integrationTest./gradlew uiTest./gradlew check./gradlew jacocoTestCoverageVerification./gradlew jacocoAllReport(CI artifact source)
Coverage thresholds are enforced in Gradle and CI. The HTML JaCoCo report is uploaded as a CI artifact, and line/branch coverage is published to the GitHub Actions Summary for the Linux job.
- Unit tests (
src/test/java) check protocol, bot command handling, and UI model invariants. - Integration tests (
src/integrationTest/java) exercise full server/client socket flow, handshake failures, resource limits, timeouts, and multiple peers. - UI smoke tests (
src/uiTest/java) verify Swing state rendering. - Future hardening tests: contract validation and error-handling matrix can be added in the same structure.
The repository runs:
checkstylefor style and API cleanliness,spotlessfor deterministic formatting,spotbugsfor bug-pattern analysis,jaCoColine/branch coverage gate on core network/protocol layers (70%/65%),- GitHub Actions pipeline on Linux + Windows,
- grouped dependency and workflow update signals via Dependabot,
- CodeQL and OpenSSF Scorecard security scans.
The quality surface keeps the main branch auditable and maintainable through automated checks,
explicit licensing, and operating docs.
- English project documentation in this file.
- Russian project documentation in
README.md.
This repository is organized for maintainability:
- explicit package structure,
- reproducible build and command surface (
./gradlew), - consistent protocol encoding,
- targeted comments in non-trivial methods,
- automated quality gates.
- Linux + Windows CI matrix for broader platform evidence.
- Automated quality gates via Checkstyle, Spotless, SpotBugs and JaCoCo.
- Security checks via CodeQL and OpenSSF Scorecard.
- Dependency and workflow automation via Dependabot.
- Explicit contributor and security docs.
Address already in use: run the server on another port, for example./gradlew runServer --args="--port 1600".- GUI does not render in CI: UI smoke tests skip automatically in headless environments.
- Client disconnects immediately: check username uniqueness and nickname length (
3..64, letters, digits,_,-). - Client receives
Server is busy: the configuredChatServerConfig.maxClientslimit has been reached. - GUI shows
No connection: check host/port and use the reconnect button; the last entered settings are stored locally. - A corrupt line in the history file is skipped during startup; valid history still loads.
Authentication failed: check the user row inaccounts.csvand the GUI token field orNETWORK_CHAT_TOKEN.- TLS trust errors: set
NETWORK_CHAT_TRUSTSTOREon the client or use a certificate trusted by the JVM.
- v1.6.x: TLS, token accounts, release packaging, and security hardening are implemented in the current line.
- Later: persistent user profiles and richer administration as separate product-focused phases.