Solon v4.0.5 landed on August 12, 2026 — a small but practical release that touches networking, HTTP client behavior, serialization, and a few internals. Here's what changed and why it matters if you're building with Solon.
1. WebSocket heartbeat: sendPing() / sendPong()
The WebSocket API in solon-net now ships dedicated sendPing() and sendPong() methods, with matching adapters across the underlying server implementations.
If you've ever kept a WebSocket connection alive against a load balancer or a proxy with an idle timeout (nginx's proxy_read_timeout, for instance), you know the drill: without periodic control frames, the connection silently dies. Before, you had to build the ping frames yourself. Now it's a first-class call:
ws.sendPing(); // send a ping control frame
ws.sendPong(); // send a pong control frame
For chat apps, dashboards, or any long-lived push channel, adding a heartbeat loop just got a lot simpler.
2. solon-net-httputils: a default User-Agent
HTTP clients built with solon-net-httputils now send a default User-Agent header — solon-http/<version> — so servers can identify your client without extra configuration.
It's fully configurable through HttpConfiguration:
// global override
HttpConfiguration.setUserAgent("my-app/1.0 (monitoring)");
// or disable the default entirely
HttpConfiguration.setUserAgent(null);
Set it once at startup and every request from your service carries the header you want.
3. Serialization: solon-serialization-fory replaces fury
A new plugin solon-serialization-fory joins the family, and the previous solon-serialization-fury is marked deprecated in favor of it.
If you're on the Fury-based serialization path, switch your dependency:
<dependency>
<groupId>org.noear</groupId>
<artifactId>solon-serialization-fory</artifactId>
</dependency>
4. MultiMap.from() now speaks picocli
MultiMap.from() — the little helper for parsing command-line args into a multi-value map — was optimized in v4.0.5 to be compatible with picocli's parsing strategy. If you build CLI-style entry points (or tools that share arg conventions with picocli-based apps), the parsing behavior now aligns where it previously diverged.
5. Under the hood: smaller packages, cleaner logs
Several internal changes worth knowing about:
- solon-server-feathttp is now imported from source instead of packaged separately — the release artifact gets smaller.
-
A StatusException fix in solon-handle:
AbstractEntityReader.doReadArgumentnow propagatesStatusExceptioncorrectly (previously it could be swallowed during argument reading). This ties into how Solon maps client-side errors to HTTP status codes like 400/404/405/415 — something I covered in the exception article a few days ago. -
feat upgraded to 2.3.1: the
serverheader is no longer emitted by default, logging moved to slf4j, and the leftoverSystem.outlogging is gone.
6. Dependency refresh
As usual, the release bumps its underlying libraries:
| Library | Version |
|---|---|
| eggg | 1.1.4 |
| snack4 | 4.0.59 |
| fastjson | 1.2.84 |
| fastjson2 | 2.0.64 |
| smartsocket | 2.1.3 |
| smarthttp | 2.5.20 |
Upgrading
Bump the version in your pom.xml (or build.gradle):
<dependency>
<groupId>org.noear</groupId>
<artifactId>solon-parent</artifactId>
<version>4.0.5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Full changelog is on GitHub Releases and the official site. If you're running the fury serialization plugin, plan the switch to fory — and if you run WebSocket services behind a proxy, the new ping/pong helpers are a welcome QoL upgrade.
Documentation for this release: https://solon.noear.org — Solon v4.0.5 (Apache 2.0).
Top comments (0)