From ce5f13c40b28b48c719b97a3b44c63e647c8e9a6 Mon Sep 17 00:00:00 2001 From: sanjomo Date: Wed, 23 Sep 2026 22:05:23 +0530 Subject: [PATCH 1/6] feat: configure Revapi for API compatibility and mark internal classes with @Internal - Configure revapi-maven-plugin in pom.xml with embedded JSON analysis configuration - Add revapi.skip property defaulting to false for flexible local and CI control - Exclude internal implementation classes annotated with @Internal from API checks - Mark internal classes across ack, handler, messages, metrics, misc, namespace, protocol, scheduler, store, and transport with @Internal - Expose Packet, PacketType, and EngineIOVersion as public API - Restore @Deprecated Packet constructor and withNsp overload for 4.0.1 backwards compatibility - Add documented Revapi difference justifications for intentional 4.0.2 schema and protocol changes --- .../socketio4j/socketio/ack/AckManager.java | 2 + .../socketio/ack/AckSchedulerKey.java | 2 + .../socketio/handler/AuthorizeHandler.java | 2 + .../socketio/handler/ClientHead.java | 2 + .../socketio/handler/ClientsBox.java | 2 + .../socketio/handler/EncoderHandler.java | 2 + .../socketio/handler/InPacketHandler.java | 2 + .../socketio/handler/PacketListener.java | 2 + .../socketio/handler/TransportState.java | 2 + .../socketio/handler/WrongUrlHandler.java | 3 + .../socketio/messages/HttpErrorMessage.java | 3 + .../socketio/messages/HttpMessage.java | 3 + .../socketio/messages/OutPacketMessage.java | 2 + .../socketio/messages/PacketsMessage.java | 2 + .../socketio/messages/XHROptionsMessage.java | 3 + .../socketio/messages/XHRPostMessage.java | 3 + .../socketio/metrics/NamespaceMeters.java | 3 + .../socketio/misc/CompositeIterable.java | 3 + .../socketio/misc/CompositeIterator.java | 3 + .../socketio/misc/IterableCollection.java | 3 + .../socketio/namespace/EventEntry.java | 2 + .../socketio/namespace/Namespace.java | 3 +- .../socketio/namespace/NamespacesHub.java | 2 + .../socketio/protocol/AuthPacket.java | 2 + .../socketio/protocol/ConnPacket.java | 3 + .../socketio/protocol/EngineIOVersion.java | 3 - .../socketio4j/socketio/protocol/Packet.java | 24 +++- .../socketio/protocol/PacketType.java | 3 - .../socketio/protocol/UTF8CharsScanner.java | 3 + .../scheduler/CancelableScheduler.java | 3 + .../scheduler/HashedWheelScheduler.java | 3 + .../HashedWheelTimeoutScheduler.java | 4 +- .../socketio/scheduler/SchedulerKey.java | 3 + .../store/event/EventMessageJsonSupport.java | 2 + .../socketio/transport/PollingTransport.java | 2 + .../transport/WebSocketTransport.java | 2 + pom.xml | 124 +++++++++++++++++- revapi.json | 91 +++++++++++++ 38 files changed, 316 insertions(+), 12 deletions(-) create mode 100644 revapi.json diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/ack/AckManager.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/ack/AckManager.java index 32888137..4d560ba5 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/ack/AckManager.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/ack/AckManager.java @@ -33,12 +33,14 @@ import com.socketio4j.socketio.MultiTypeAckCallback; import com.socketio4j.socketio.MultiTypeArgs; import com.socketio4j.socketio.SocketIOClient; +import com.socketio4j.socketio.annotation.Internal; import com.socketio4j.socketio.handler.ClientHead; import com.socketio4j.socketio.protocol.Packet; import com.socketio4j.socketio.scheduler.CancelableScheduler; import com.socketio4j.socketio.scheduler.SchedulerKey; import com.socketio4j.socketio.scheduler.SchedulerKey.Type; +@Internal public class AckManager implements Disconnectable { static class AckEntry { diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/ack/AckSchedulerKey.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/ack/AckSchedulerKey.java index 902097fb..9c6d25d2 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/ack/AckSchedulerKey.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/ack/AckSchedulerKey.java @@ -18,8 +18,10 @@ import java.util.UUID; +import com.socketio4j.socketio.annotation.Internal; import com.socketio4j.socketio.scheduler.SchedulerKey; +@Internal public class AckSchedulerKey extends SchedulerKey { private final long index; diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/handler/AuthorizeHandler.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/handler/AuthorizeHandler.java index a5e6c884..172649c7 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/handler/AuthorizeHandler.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/handler/AuthorizeHandler.java @@ -37,6 +37,7 @@ import com.socketio4j.socketio.SocketIOClient; import com.socketio4j.socketio.Transport; import com.socketio4j.socketio.ack.AckManager; +import com.socketio4j.socketio.annotation.Internal; import com.socketio4j.socketio.messages.HttpErrorMessage; import com.socketio4j.socketio.namespace.Namespace; import com.socketio4j.socketio.namespace.NamespacesHub; @@ -70,6 +71,7 @@ import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1; +@Internal @Sharable public class AuthorizeHandler extends ChannelInboundHandlerAdapter implements Disconnectable { diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/handler/ClientHead.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/handler/ClientHead.java index 2799967e..7b05c2b3 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/handler/ClientHead.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/handler/ClientHead.java @@ -41,6 +41,7 @@ import com.socketio4j.socketio.HandshakeData; import com.socketio4j.socketio.Transport; import com.socketio4j.socketio.ack.AckManager; +import com.socketio4j.socketio.annotation.Internal; import com.socketio4j.socketio.messages.OutPacketMessage; import com.socketio4j.socketio.namespace.Namespace; import com.socketio4j.socketio.protocol.EngineIOVersion; @@ -60,6 +61,7 @@ import io.netty.handler.codec.http.HttpHeaderNames; import io.netty.util.AttributeKey; +@Internal public class ClientHead { private static final Logger log = LoggerFactory.getLogger(ClientHead.class); diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/handler/ClientsBox.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/handler/ClientsBox.java index ce8312a3..523df08e 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/handler/ClientsBox.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/handler/ClientsBox.java @@ -21,9 +21,11 @@ import java.util.concurrent.ConcurrentHashMap; import com.socketio4j.socketio.HandshakeData; +import com.socketio4j.socketio.annotation.Internal; import io.netty.channel.Channel; +@Internal public class ClientsBox { private final Map uuid2clients = new ConcurrentHashMap<>(); diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/handler/EncoderHandler.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/handler/EncoderHandler.java index 151ffd67..8a7b8edf 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/handler/EncoderHandler.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/handler/EncoderHandler.java @@ -31,6 +31,7 @@ import com.socketio4j.socketio.Configuration; import com.socketio4j.socketio.Transport; +import com.socketio4j.socketio.annotation.Internal; import com.socketio4j.socketio.messages.HttpErrorMessage; import com.socketio4j.socketio.messages.HttpMessage; import com.socketio4j.socketio.messages.OutPacketMessage; @@ -71,6 +72,7 @@ import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1; +@Internal @Sharable public class EncoderHandler extends ChannelOutboundHandlerAdapter { diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/handler/InPacketHandler.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/handler/InPacketHandler.java index 19e1c3f6..d1bed14c 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/handler/InPacketHandler.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/handler/InPacketHandler.java @@ -23,6 +23,7 @@ import org.slf4j.LoggerFactory; import com.socketio4j.socketio.AuthTokenResult; +import com.socketio4j.socketio.annotation.Internal; import com.socketio4j.socketio.listener.ExceptionListener; import com.socketio4j.socketio.messages.PacketsMessage; import com.socketio4j.socketio.namespace.Namespace; @@ -40,6 +41,7 @@ import io.netty.channel.SimpleChannelInboundHandler; import io.netty.util.CharsetUtil; +@Internal @Sharable public class InPacketHandler extends SimpleChannelInboundHandler { diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/handler/PacketListener.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/handler/PacketListener.java index e30970a0..4e0c839a 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/handler/PacketListener.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/handler/PacketListener.java @@ -22,6 +22,7 @@ import com.socketio4j.socketio.AckRequest; import com.socketio4j.socketio.Transport; import com.socketio4j.socketio.ack.AckManager; +import com.socketio4j.socketio.annotation.Internal; import com.socketio4j.socketio.namespace.Namespace; import com.socketio4j.socketio.namespace.NamespacesHub; import com.socketio4j.socketio.protocol.EngineIOVersion; @@ -34,6 +35,7 @@ import io.netty.channel.ChannelFuture; +@Internal public class PacketListener { private final NamespacesHub namespacesHub; diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/handler/TransportState.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/handler/TransportState.java index aafe024d..75c12a1b 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/handler/TransportState.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/handler/TransportState.java @@ -20,10 +20,12 @@ import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.atomic.AtomicReference; +import com.socketio4j.socketio.annotation.Internal; import com.socketio4j.socketio.protocol.Packet; import io.netty.channel.Channel; +@Internal public class TransportState { private Queue packetsQueue = new ConcurrentLinkedQueue<>(); diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/handler/WrongUrlHandler.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/handler/WrongUrlHandler.java index 335eff52..2809b4f5 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/handler/WrongUrlHandler.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/handler/WrongUrlHandler.java @@ -19,6 +19,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.socketio4j.socketio.annotation.Internal; + import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFutureListener; @@ -33,6 +35,7 @@ import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1; +@Internal @Sharable public class WrongUrlHandler extends ChannelInboundHandlerAdapter { diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/messages/HttpErrorMessage.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/messages/HttpErrorMessage.java index 0c51d71e..8bcee57d 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/messages/HttpErrorMessage.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/messages/HttpErrorMessage.java @@ -18,6 +18,9 @@ import java.util.Map; +import com.socketio4j.socketio.annotation.Internal; + +@Internal public class HttpErrorMessage extends HttpMessage { private final Map data; diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/messages/HttpMessage.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/messages/HttpMessage.java index cdf3580a..11cc5d2b 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/messages/HttpMessage.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/messages/HttpMessage.java @@ -18,6 +18,9 @@ import java.util.UUID; +import com.socketio4j.socketio.annotation.Internal; + +@Internal public abstract class HttpMessage { private final String origin; diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/messages/OutPacketMessage.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/messages/OutPacketMessage.java index c06e8814..6b3783b6 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/messages/OutPacketMessage.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/messages/OutPacketMessage.java @@ -17,8 +17,10 @@ package com.socketio4j.socketio.messages; import com.socketio4j.socketio.Transport; +import com.socketio4j.socketio.annotation.Internal; import com.socketio4j.socketio.handler.ClientHead; +@Internal public class OutPacketMessage extends HttpMessage { private final ClientHead clientHead; diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/messages/PacketsMessage.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/messages/PacketsMessage.java index 7d445c8e..fb550e01 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/messages/PacketsMessage.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/messages/PacketsMessage.java @@ -17,11 +17,13 @@ package com.socketio4j.socketio.messages; import com.socketio4j.socketio.Transport; +import com.socketio4j.socketio.annotation.Internal; import com.socketio4j.socketio.handler.ClientHead; import io.netty.buffer.ByteBuf; import io.netty.util.ReferenceCounted; +@Internal public class PacketsMessage implements ReferenceCounted { private final ClientHead client; diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/messages/XHROptionsMessage.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/messages/XHROptionsMessage.java index cfdad4aa..559d320c 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/messages/XHROptionsMessage.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/messages/XHROptionsMessage.java @@ -18,6 +18,9 @@ import java.util.UUID; +import com.socketio4j.socketio.annotation.Internal; + +@Internal public class XHROptionsMessage extends XHRPostMessage { public XHROptionsMessage(String origin, UUID sessionId) { diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/messages/XHRPostMessage.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/messages/XHRPostMessage.java index eefde260..d00c81f8 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/messages/XHRPostMessage.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/messages/XHRPostMessage.java @@ -18,6 +18,9 @@ import java.util.UUID; +import com.socketio4j.socketio.annotation.Internal; + +@Internal public class XHRPostMessage extends HttpMessage { public XHRPostMessage(String origin, UUID sessionId) { diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/metrics/NamespaceMeters.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/metrics/NamespaceMeters.java index d3f32212..4e3d369b 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/metrics/NamespaceMeters.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/metrics/NamespaceMeters.java @@ -21,6 +21,8 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; +import com.socketio4j.socketio.annotation.Internal; + import io.micrometer.core.instrument.Counter; import io.micrometer.core.instrument.Gauge; import io.micrometer.core.instrument.MeterRegistry; @@ -38,6 +40,7 @@ * @author https://github.com/sanjomo * @date 05/01/26 3:10 pm */ +@Internal public final class NamespaceMeters { /* ===================== Event Counters ===================== */ diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/misc/CompositeIterable.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/misc/CompositeIterable.java index 3dd003da..937204cf 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/misc/CompositeIterable.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/misc/CompositeIterable.java @@ -20,6 +20,9 @@ import java.util.Iterator; import java.util.List; +import com.socketio4j.socketio.annotation.Internal; + +@Internal public class CompositeIterable implements Iterable { private List> iterablesList; diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/misc/CompositeIterator.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/misc/CompositeIterator.java index 74c2eed0..cecbaa4e 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/misc/CompositeIterator.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/misc/CompositeIterator.java @@ -18,6 +18,9 @@ import java.util.Iterator; +import com.socketio4j.socketio.annotation.Internal; + +@Internal public class CompositeIterator implements Iterator { private final Iterator> listIterator; diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/misc/IterableCollection.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/misc/IterableCollection.java index 6178ee1f..09ad9044 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/misc/IterableCollection.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/misc/IterableCollection.java @@ -19,6 +19,9 @@ import java.util.AbstractCollection; import java.util.Iterator; +import com.socketio4j.socketio.annotation.Internal; + +@Internal public class IterableCollection extends AbstractCollection { private final CompositeIterable iterable; diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/namespace/EventEntry.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/namespace/EventEntry.java index 74df8cbc..d70d932d 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/namespace/EventEntry.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/namespace/EventEntry.java @@ -19,8 +19,10 @@ import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; +import com.socketio4j.socketio.annotation.Internal; import com.socketio4j.socketio.listener.DataListener; +@Internal public class EventEntry { private final Queue> listeners = new ConcurrentLinkedQueue>(); diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/namespace/Namespace.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/namespace/Namespace.java index 6aebfee7..d5a9236d 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/namespace/Namespace.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/namespace/Namespace.java @@ -45,6 +45,7 @@ import com.socketio4j.socketio.SingleRoomBroadcastOperations; import com.socketio4j.socketio.SocketIOClient; import com.socketio4j.socketio.SocketIONamespace; +import com.socketio4j.socketio.annotation.Internal; import com.socketio4j.socketio.annotation.ScannerEngine; import com.socketio4j.socketio.listener.CatchAllEventListener; import com.socketio4j.socketio.listener.ConnectListener; @@ -66,13 +67,13 @@ import com.socketio4j.socketio.store.event.LeaveMessage; import com.socketio4j.socketio.transport.NamespaceClient; - /** * Hub object for all clients in one namespace. * Namespace shares by different namespace-clients. * * @see com.socketio4j.socketio.transport.NamespaceClient */ +@Internal public class Namespace implements SocketIONamespace { private static final Logger log = LoggerFactory.getLogger(Namespace.class); diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/namespace/NamespacesHub.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/namespace/NamespacesHub.java index ccb96d58..1a902fb9 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/namespace/NamespacesHub.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/namespace/NamespacesHub.java @@ -25,8 +25,10 @@ import com.socketio4j.socketio.Configuration; import com.socketio4j.socketio.SocketIOClient; import com.socketio4j.socketio.SocketIONamespace; +import com.socketio4j.socketio.annotation.Internal; import com.socketio4j.socketio.misc.CompositeIterable; +@Internal public class NamespacesHub { private final ConcurrentMap namespaces = new ConcurrentHashMap<>(); diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/protocol/AuthPacket.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/protocol/AuthPacket.java index 21dc908e..ace3a9f6 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/protocol/AuthPacket.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/protocol/AuthPacket.java @@ -18,7 +18,9 @@ import java.util.UUID; +import com.socketio4j.socketio.annotation.Internal; +@Internal public class AuthPacket { private final UUID sid; diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/protocol/ConnPacket.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/protocol/ConnPacket.java index 34d56271..e062d2d1 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/protocol/ConnPacket.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/protocol/ConnPacket.java @@ -18,6 +18,9 @@ import java.util.UUID; +import com.socketio4j.socketio.annotation.Internal; + +@Internal public class ConnPacket { private final UUID sid; diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/protocol/EngineIOVersion.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/protocol/EngineIOVersion.java index ad282049..bfc80d7e 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/protocol/EngineIOVersion.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/protocol/EngineIOVersion.java @@ -19,12 +19,9 @@ import java.util.HashMap; import java.util.Map; -import com.socketio4j.socketio.annotation.Internal; - /** * Engine.IO protocol version */ -@Internal public enum EngineIOVersion { /** * @link Engine.IO version 2 diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/protocol/Packet.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/protocol/Packet.java index 53917113..b67efb3f 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/protocol/Packet.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/protocol/Packet.java @@ -21,12 +21,10 @@ import java.util.Collections; import java.util.List; -import com.socketio4j.socketio.annotation.Internal; import com.socketio4j.socketio.namespace.Namespace; import io.netty.buffer.ByteBuf; -@Internal public class Packet implements Serializable { private static final long serialVersionUID = 4560159536486711426L; @@ -52,6 +50,14 @@ public Packet(PacketType type) { this.type = type; } + /** + * @deprecated Engine.IO version is now negotiated per-connection. Use {@link #Packet(PacketType)} instead. + */ + @Deprecated + public Packet(PacketType type, EngineIOVersion engineIOVersion) { + this(type); + } + public PacketType getSubType() { return subType; } @@ -88,7 +94,6 @@ public T getData() { * Otherwise, returns original object unchanged * * @param namespace - * @param engineIOVersion * @return packet */ public Packet withNsp(String namespace) { @@ -106,6 +111,19 @@ public Packet withNsp(String namespace) { return newPacket; } } + + /** + * Creates a copy of #{@link Packet} with new namespace set. + * + * @deprecated Engine.IO version is now negotiated per-connection. Use {@link #withNsp(String)} instead. + * @param namespace + * @param engineIOVersion + * @return packet + */ + @Deprecated + public Packet withNsp(String namespace, EngineIOVersion engineIOVersion) { + return withNsp(namespace); + } public void setNsp(String endpoint) { //patch for #903 if ("{}".equals(endpoint)){ diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/protocol/PacketType.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/protocol/PacketType.java index 718c3c72..bb3423bb 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/protocol/PacketType.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/protocol/PacketType.java @@ -17,9 +17,6 @@ package com.socketio4j.socketio.protocol; -import com.socketio4j.socketio.annotation.Internal; - -@Internal public enum PacketType { OPEN(0), CLOSE(1), PING(2), PONG(3), MESSAGE(4), UPGRADE(5), NOOP(6), diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/protocol/UTF8CharsScanner.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/protocol/UTF8CharsScanner.java index 7d1ecc82..89fb0e21 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/protocol/UTF8CharsScanner.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/protocol/UTF8CharsScanner.java @@ -16,8 +16,11 @@ */ package com.socketio4j.socketio.protocol; +import com.socketio4j.socketio.annotation.Internal; + import io.netty.buffer.ByteBuf; +@Internal public class UTF8CharsScanner { /** diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/scheduler/CancelableScheduler.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/scheduler/CancelableScheduler.java index 1accc102..d35eb7ab 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/scheduler/CancelableScheduler.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/scheduler/CancelableScheduler.java @@ -18,8 +18,11 @@ import java.util.concurrent.TimeUnit; +import com.socketio4j.socketio.annotation.Internal; + import io.netty.channel.ChannelHandlerContext; +@Internal public interface CancelableScheduler { void update(ChannelHandlerContext ctx); diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/scheduler/HashedWheelScheduler.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/scheduler/HashedWheelScheduler.java index b0ce4000..7d0bef3e 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/scheduler/HashedWheelScheduler.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/scheduler/HashedWheelScheduler.java @@ -21,10 +21,13 @@ import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; +import com.socketio4j.socketio.annotation.Internal; + import io.netty.channel.ChannelHandlerContext; import io.netty.util.HashedWheelTimer; import io.netty.util.Timeout; +@Internal public class HashedWheelScheduler implements CancelableScheduler { private final Map scheduledFutures = new ConcurrentHashMap<>(); diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/scheduler/HashedWheelTimeoutScheduler.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/scheduler/HashedWheelTimeoutScheduler.java index 93242e9b..aba289fa 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/scheduler/HashedWheelTimeoutScheduler.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/scheduler/HashedWheelTimeoutScheduler.java @@ -30,11 +30,13 @@ import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; +import com.socketio4j.socketio.annotation.Internal; + import io.netty.channel.ChannelHandlerContext; import io.netty.util.HashedWheelTimer; import io.netty.util.Timeout; - +@Internal public class HashedWheelTimeoutScheduler implements CancelableScheduler { private final ConcurrentMap scheduledFutures = new ConcurrentHashMap<>(); diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/scheduler/SchedulerKey.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/scheduler/SchedulerKey.java index b5239cb0..ce0b9e23 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/scheduler/SchedulerKey.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/scheduler/SchedulerKey.java @@ -17,6 +17,9 @@ package com.socketio4j.socketio.scheduler; +import com.socketio4j.socketio.annotation.Internal; + +@Internal public class SchedulerKey { public enum Type {PING, PING_TIMEOUT, ACK_TIMEOUT, UPGRADE_TIMEOUT, POLL_FLUSH_TIMEOUT}; diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/store/event/EventMessageJsonSupport.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/store/event/EventMessageJsonSupport.java index d146ed29..bfc9f3aa 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/store/event/EventMessageJsonSupport.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/store/event/EventMessageJsonSupport.java @@ -39,12 +39,14 @@ import com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer; import com.fasterxml.jackson.databind.json.JsonMapper; import com.fasterxml.jackson.databind.module.SimpleModule; +import com.socketio4j.socketio.annotation.Internal; /** * Shared JSON ObjectMapper builder for JSON-based EventStores (NATS, Kafka, Redis Streams, etc.). * Guarantees lossless JSON serialization and deserialization of binary byte arrays (byte[]) * embedded inside EventMessages and Packets. */ +@Internal public final class EventMessageJsonSupport { private static final String BYTES_FIELD = "$bytes"; private EventMessageJsonSupport() { diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/transport/PollingTransport.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/transport/PollingTransport.java index e335207d..95e85c3a 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/transport/PollingTransport.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/transport/PollingTransport.java @@ -27,6 +27,7 @@ import org.slf4j.LoggerFactory; import com.socketio4j.socketio.Transport; +import com.socketio4j.socketio.annotation.Internal; import com.socketio4j.socketio.handler.AuthorizeHandler; import com.socketio4j.socketio.handler.ClientHead; import com.socketio4j.socketio.handler.ClientsBox; @@ -53,6 +54,7 @@ import io.netty.handler.codec.http.QueryStringDecoder; import io.netty.handler.codec.http.websocketx.WebSocket13FrameDecoder; +@Internal @Sharable public class PollingTransport extends ChannelInboundHandlerAdapter { diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/transport/WebSocketTransport.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/transport/WebSocketTransport.java index e39e54db..ee8a7d11 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/transport/WebSocketTransport.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/transport/WebSocketTransport.java @@ -26,6 +26,7 @@ import com.socketio4j.socketio.Configuration; import com.socketio4j.socketio.SocketIOChannelInitializer; import com.socketio4j.socketio.Transport; +import com.socketio4j.socketio.annotation.Internal; import com.socketio4j.socketio.handler.AuthorizeHandler; import com.socketio4j.socketio.handler.ClientHead; import com.socketio4j.socketio.handler.ClientsBox; @@ -64,6 +65,7 @@ import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1; +@Internal @Sharable public class WebSocketTransport extends ChannelInboundHandlerAdapter { diff --git a/pom.xml b/pom.xml index 1209a3ca..a4db66d5 100644 --- a/pom.xml +++ b/pom.xml @@ -91,7 +91,9 @@ 1.10.3 3.12.13 1 - + 0.15.1 + 0.28.4 + false @@ -692,6 +694,126 @@ + + + org.revapi + revapi-maven-plugin + ${revapi-maven-plugin.version} + + + org.revapi + revapi-java + ${revapi-java.version} + + + + ${revapi.skip} + false + error + false + + [ + { + "extension": "revapi.java", + "configuration": { + "missing-classes": { + "behavior": "ignore" + } + } + }, + { + "extension": "revapi.filter", + "configuration": { + "elements": { + "exclude": [ + { + "matcher": "java", + "match": "@com.socketio4j.socketio.annotation.Internal ^*;" + } + ] + } + } + }, + { + "extension": "revapi.differences", + "configuration": { + "ignore": true, + "differences": [ + { + "code": "java.class.removed", + "regex": true, + "old": ".*com\\.socketio4j\\.socketio\\.(ack|handler|transport|messages|protocol|scheduler|misc|namespace|metrics|store\\.event)\\..*", + "justification": "Marked internal implementation classes with @Internal to define clean API boundaries" + }, + { + "code": "java.annotation.added", + "annotation": "@org.jetbrains.annotations.Nullable", + "justification": "Added nullability annotations for enhanced type safety and Kotlin interop" + }, + { + "code": "java.method.exception.checkedRemoved", + "justification": "Removing checked Exception makes listener methods easier to implement without boilerplate throws clause" + }, + { + "code": "java.method.removed", + "old": "method void com.socketio4j.socketio.handler.ClientHead::setLastBinaryPacket(com.socketio4j.socketio.protocol.Packet)", + "justification": "Internal binary packet handling moved to dedicated pipeline handler" + }, + { + "code": "java.method.addedToInterface", + "new": "method void com.socketio4j.socketio.listener.ClientListeners::removeConnectListener(com.socketio4j.socketio.listener.ConnectListener)", + "justification": "Added default method to allow dynamic unregistering of connect listeners" + }, + { + "code": "java.method.addedToInterface", + "new": "method void com.socketio4j.socketio.listener.ClientListeners::removeDisconnectListener(com.socketio4j.socketio.listener.DisconnectListener)", + "justification": "Added default method to allow dynamic unregistering of disconnect listeners" + }, + { + "code": "java.field.removed", + "old": "field com.socketio4j.socketio.protocol.EngineIOVersion.UNKNOWN", + "justification": "Removed UNKNOWN enum value; handshakes must validate protocol revisions via EngineIOVersion.isSupported() and fall back to V4" + }, + { + "code": "java.field.serialVersionUIDUnchanged", + "old": "field com.socketio4j.socketio.protocol.Packet.serialVersionUID", + "justification": "Packet serialization schema evolved; serialVersionUID maintained for backwards compatibility" + }, + { + "code": "java.method.removed", + "old": "method io.netty.buffer.ByteBuf com.socketio4j.socketio.protocol.Packet::getDataSource()", + "justification": "Internal Netty buffer data source handling moved to pipeline decoders and attachments" + }, + { + "code": "java.method.removed", + "old": "method void com.socketio4j.socketio.protocol.Packet::setDataSource(io.netty.buffer.ByteBuf)", + "justification": "Internal Netty buffer data source handling moved to pipeline decoders and attachments" + }, + { + "code": "java.method.removed", + "old": "method com.socketio4j.socketio.protocol.EngineIOVersion com.socketio4j.socketio.protocol.Packet::getEngineIOVersion()", + "justification": "Engine.IO versioning is negotiated per-connection on ClientHead/SocketIOClient rather than per-packet" + }, + { + "code": "java.method.removed", + "old": "method void com.socketio4j.socketio.protocol.Packet::setEngineIOVersion(com.socketio4j.socketio.protocol.EngineIOVersion)", + "justification": "Engine.IO versioning is negotiated per-connection on ClientHead/SocketIOClient rather than per-packet" + } + ] + } + } + ] + + + + + check-api + + check + + + + diff --git a/revapi.json b/revapi.json new file mode 100644 index 00000000..f2defbff --- /dev/null +++ b/revapi.json @@ -0,0 +1,91 @@ +[ + { + "extension": "revapi.java", + "configuration": { + "missing-classes": { + "behavior": "ignore" + } + } + }, + { + "extension": "revapi.filter", + "configuration": { + "elements": { + "exclude": [ + { + "matcher": "java", + "match": "@com.socketio4j.socketio.annotation.Internal ^*;" + } + ] + } + } + }, + { + "extension": "revapi.differences", + "configuration": { + "ignore": true, + "differences": [ + { + "code": "java.class.removed", + "regex": true, + "old": ".*com\\.socketio4j\\.socketio\\.(ack|handler|transport|messages|protocol|scheduler|misc|namespace|metrics|store\\.event)\\..*", + "justification": "Marked internal implementation classes with @Internal to define clean API boundaries" + }, + { + "code": "java.annotation.added", + "annotation": "@org.jetbrains.annotations.Nullable", + "justification": "Added nullability annotations for enhanced type safety and Kotlin interop" + }, + { + "code": "java.method.exception.checkedRemoved", + "justification": "Removing checked Exception makes listener methods easier to implement without boilerplate throws clause" + }, + { + "code": "java.method.removed", + "old": "method void com.socketio4j.socketio.handler.ClientHead::setLastBinaryPacket(com.socketio4j.socketio.protocol.Packet)", + "justification": "Internal binary packet handling moved to dedicated pipeline handler" + }, + { + "code": "java.method.addedToInterface", + "new": "method void com.socketio4j.socketio.listener.ClientListeners::removeConnectListener(com.socketio4j.socketio.listener.ConnectListener)", + "justification": "Added default method to allow dynamic unregistering of connect listeners" + }, + { + "code": "java.method.addedToInterface", + "new": "method void com.socketio4j.socketio.listener.ClientListeners::removeDisconnectListener(com.socketio4j.socketio.listener.DisconnectListener)", + "justification": "Added default method to allow dynamic unregistering of disconnect listeners" + }, + { + "code": "java.field.removed", + "old": "field com.socketio4j.socketio.protocol.EngineIOVersion.UNKNOWN", + "justification": "Removed UNKNOWN enum value; handshakes must validate protocol revisions via EngineIOVersion.isSupported() and fall back to V4" + }, + { + "code": "java.field.serialVersionUIDUnchanged", + "old": "field com.socketio4j.socketio.protocol.Packet.serialVersionUID", + "justification": "Packet serialization schema evolved; serialVersionUID maintained for backwards compatibility" + }, + { + "code": "java.method.removed", + "old": "method io.netty.buffer.ByteBuf com.socketio4j.socketio.protocol.Packet::getDataSource()", + "justification": "Internal Netty buffer data source handling moved to pipeline decoders and attachments" + }, + { + "code": "java.method.removed", + "old": "method void com.socketio4j.socketio.protocol.Packet::setDataSource(io.netty.buffer.ByteBuf)", + "justification": "Internal Netty buffer data source handling moved to pipeline decoders and attachments" + }, + { + "code": "java.method.removed", + "old": "method com.socketio4j.socketio.protocol.EngineIOVersion com.socketio4j.socketio.protocol.Packet::getEngineIOVersion()", + "justification": "Engine.IO versioning is negotiated per-connection on ClientHead/SocketIOClient rather than per-packet" + }, + { + "code": "java.method.removed", + "old": "method void com.socketio4j.socketio.protocol.Packet::setEngineIOVersion(com.socketio4j.socketio.protocol.EngineIOVersion)", + "justification": "Engine.IO versioning is negotiated per-connection on ClientHead/SocketIOClient rather than per-packet" + } + ] + } + } +] From 95066d22fa8791e15fd4a5e17312b02d003eaa0b Mon Sep 17 00:00:00 2001 From: sanjomo Date: Wed, 23 Sep 2026 22:12:07 +0530 Subject: [PATCH 2/6] feat: restore bytecode compatibility bridges for Packet and EngineIOVersion - Restore @Deprecated UNKNOWN on EngineIOVersion - Restore @Deprecated getEngineIOVersion, setEngineIOVersion, getDataSource, and setDataSource on Packet - Remove corresponding difference ignore rules from pom.xml and revapi.json to strictly enforce bytecode compatibility --- .../socketio/protocol/EngineIOVersion.java | 12 +++++-- .../socketio4j/socketio/protocol/Packet.java | 31 +++++++++++++++++++ pom.xml | 25 --------------- revapi.json | 25 --------------- 4 files changed, 41 insertions(+), 52 deletions(-) diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/protocol/EngineIOVersion.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/protocol/EngineIOVersion.java index bfc80d7e..77b43b50 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/protocol/EngineIOVersion.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/protocol/EngineIOVersion.java @@ -35,7 +35,13 @@ public enum EngineIOVersion { * current version * @link Engine.IO version 4 */ - V4("4"); + V4("4"), + + /** + * @deprecated Unknown revisions are rejected in handshake; use {@link #isSupported(String)} + */ + @Deprecated + UNKNOWN(""); public static final String EIO = "EIO"; @@ -43,7 +49,9 @@ public enum EngineIOVersion { static { for (EngineIOVersion value : values()) { - VERSIONS.put(value.getValue(), value); + if (value != UNKNOWN) { + VERSIONS.put(value.getValue(), value); + } } } diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/protocol/Packet.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/protocol/Packet.java index b67efb3f..1e9dee94 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/protocol/Packet.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/protocol/Packet.java @@ -174,6 +174,37 @@ public boolean hasAttachments() { public boolean isAttachmentsLoaded() { return this.attachments.size() == attachmentsCount; } + /** + * @deprecated Engine.IO version is now negotiated per-connection. + */ + @Deprecated + public EngineIOVersion getEngineIOVersion() { + return EngineIOVersion.V4; + } + + /** + * @deprecated Engine.IO version is now negotiated per-connection. + */ + @Deprecated + public void setEngineIOVersion(EngineIOVersion engineIOVersion) { + // no-op: version is now negotiated per-connection + } + + /** + * @deprecated Binary attachments are handled via {@link #getAttachments()}. + */ + @Deprecated + public ByteBuf getDataSource() { + return null; + } + + /** + * @deprecated Binary attachments are handled via {@link #addAttachment(ByteBuf)}. + */ + @Deprecated + public void setDataSource(ByteBuf dataSource) { + // no-op: data source is handled via attachments/decoders + } @Override public String toString() { diff --git a/pom.xml b/pom.xml index a4db66d5..4f7af15b 100644 --- a/pom.xml +++ b/pom.xml @@ -769,35 +769,10 @@ "new": "method void com.socketio4j.socketio.listener.ClientListeners::removeDisconnectListener(com.socketio4j.socketio.listener.DisconnectListener)", "justification": "Added default method to allow dynamic unregistering of disconnect listeners" }, - { - "code": "java.field.removed", - "old": "field com.socketio4j.socketio.protocol.EngineIOVersion.UNKNOWN", - "justification": "Removed UNKNOWN enum value; handshakes must validate protocol revisions via EngineIOVersion.isSupported() and fall back to V4" - }, { "code": "java.field.serialVersionUIDUnchanged", "old": "field com.socketio4j.socketio.protocol.Packet.serialVersionUID", "justification": "Packet serialization schema evolved; serialVersionUID maintained for backwards compatibility" - }, - { - "code": "java.method.removed", - "old": "method io.netty.buffer.ByteBuf com.socketio4j.socketio.protocol.Packet::getDataSource()", - "justification": "Internal Netty buffer data source handling moved to pipeline decoders and attachments" - }, - { - "code": "java.method.removed", - "old": "method void com.socketio4j.socketio.protocol.Packet::setDataSource(io.netty.buffer.ByteBuf)", - "justification": "Internal Netty buffer data source handling moved to pipeline decoders and attachments" - }, - { - "code": "java.method.removed", - "old": "method com.socketio4j.socketio.protocol.EngineIOVersion com.socketio4j.socketio.protocol.Packet::getEngineIOVersion()", - "justification": "Engine.IO versioning is negotiated per-connection on ClientHead/SocketIOClient rather than per-packet" - }, - { - "code": "java.method.removed", - "old": "method void com.socketio4j.socketio.protocol.Packet::setEngineIOVersion(com.socketio4j.socketio.protocol.EngineIOVersion)", - "justification": "Engine.IO versioning is negotiated per-connection on ClientHead/SocketIOClient rather than per-packet" } ] } diff --git a/revapi.json b/revapi.json index f2defbff..b35dc6a9 100644 --- a/revapi.json +++ b/revapi.json @@ -55,35 +55,10 @@ "new": "method void com.socketio4j.socketio.listener.ClientListeners::removeDisconnectListener(com.socketio4j.socketio.listener.DisconnectListener)", "justification": "Added default method to allow dynamic unregistering of disconnect listeners" }, - { - "code": "java.field.removed", - "old": "field com.socketio4j.socketio.protocol.EngineIOVersion.UNKNOWN", - "justification": "Removed UNKNOWN enum value; handshakes must validate protocol revisions via EngineIOVersion.isSupported() and fall back to V4" - }, { "code": "java.field.serialVersionUIDUnchanged", "old": "field com.socketio4j.socketio.protocol.Packet.serialVersionUID", "justification": "Packet serialization schema evolved; serialVersionUID maintained for backwards compatibility" - }, - { - "code": "java.method.removed", - "old": "method io.netty.buffer.ByteBuf com.socketio4j.socketio.protocol.Packet::getDataSource()", - "justification": "Internal Netty buffer data source handling moved to pipeline decoders and attachments" - }, - { - "code": "java.method.removed", - "old": "method void com.socketio4j.socketio.protocol.Packet::setDataSource(io.netty.buffer.ByteBuf)", - "justification": "Internal Netty buffer data source handling moved to pipeline decoders and attachments" - }, - { - "code": "java.method.removed", - "old": "method com.socketio4j.socketio.protocol.EngineIOVersion com.socketio4j.socketio.protocol.Packet::getEngineIOVersion()", - "justification": "Engine.IO versioning is negotiated per-connection on ClientHead/SocketIOClient rather than per-packet" - }, - { - "code": "java.method.removed", - "old": "method void com.socketio4j.socketio.protocol.Packet::setEngineIOVersion(com.socketio4j.socketio.protocol.EngineIOVersion)", - "justification": "Engine.IO versioning is negotiated per-connection on ClientHead/SocketIOClient rather than per-packet" } ] } From 790837e79759c3db5d16fc957ee41c7e356a7d52 Mon Sep 17 00:00:00 2001 From: sanjomo Date: Wed, 23 Sep 2026 22:15:49 +0530 Subject: [PATCH 3/6] build: configure strict revapi failCriticality and release unresolved baseline enforcement --- pom.xml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 4f7af15b..b167a637 100644 --- a/pom.xml +++ b/pom.xml @@ -94,11 +94,16 @@ 0.15.1 0.28.4 false + false + error release + + true + @@ -709,8 +714,8 @@ ${revapi.skip} false - error - false + ${revapi.failCriticality} + ${revapi.failOnUnresolvedArtifacts} [ { From efd6b80d73bd95351fc1f06ad5c1297e414d5703 Mon Sep 17 00:00:00 2001 From: sanjomo Date: Wed, 23 Sep 2026 22:32:23 +0530 Subject: [PATCH 4/6] build: declare explicit revapi baseline version and tighten class transition regex - Set explicit revapi.oldVersion=4.0.1 and wire into revapi-maven-plugin oldVersion - Remove brittle failOnUnresolvedArtifacts override from release profile - Tighten java.class.removed regex from broad package wildcards to exact internal classes and interfaces - Remove duplicate revapi.json to maintain single source of truth in pom.xml --- pom.xml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index b167a637..67d171ec 100644 --- a/pom.xml +++ b/pom.xml @@ -93,6 +93,7 @@ 1 0.15.1 0.28.4 + 4.0.1 false false error @@ -101,9 +102,6 @@ release - - true - @@ -712,6 +710,7 @@ + ${revapi.oldVersion} ${revapi.skip} false ${revapi.failCriticality} @@ -747,8 +746,8 @@ { "code": "java.class.removed", "regex": true, - "old": ".*com\\.socketio4j\\.socketio\\.(ack|handler|transport|messages|protocol|scheduler|misc|namespace|metrics|store\\.event)\\..*", - "justification": "Marked internal implementation classes with @Internal to define clean API boundaries" + "old": "(class|interface) com\\.socketio4j\\.socketio\\.(ack\\.(AckManager|AckSchedulerKey)|handler\\.(AuthorizeHandler|ClientHead|ClientsBox|EncoderHandler|InPacketHandler|PacketListener|TransportState|WrongUrlHandler)|messages\\.(HttpErrorMessage|HttpMessage|OutPacketMessage|PacketsMessage|XHROptionsMessage|XHRPostMessage)|metrics\\.NamespaceMeters|misc\\.(CompositeIterable.*|CompositeIterator.*|IterableCollection.*)|namespace\\.(EventEntry.*|Namespace|NamespacesHub)|protocol\\.(AuthPacket|ConnPacket|Event|PacketDecoder|PacketEncoder|UTF8CharsScanner)|scheduler\\.(CancelableScheduler|HashedWheelScheduler|HashedWheelTimeoutScheduler|SchedulerKey)|store\\.event\\.EventMessageJsonSupport|transport\\.(PollingTransport|WebSocketTransport))", + "justification": "Transitioned specific internal implementation classes to @Internal to establish API boundaries" }, { "code": "java.annotation.added", From 133362b02c06461079f27224b31e1aa7fe22dbe1 Mon Sep 17 00:00:00 2001 From: sanjomo Date: Wed, 23 Sep 2026 22:32:39 +0530 Subject: [PATCH 5/6] build: remove duplicate revapi.json to keep pom.xml as single source of truth --- revapi.json | 66 ----------------------------------------------------- 1 file changed, 66 deletions(-) delete mode 100644 revapi.json diff --git a/revapi.json b/revapi.json deleted file mode 100644 index b35dc6a9..00000000 --- a/revapi.json +++ /dev/null @@ -1,66 +0,0 @@ -[ - { - "extension": "revapi.java", - "configuration": { - "missing-classes": { - "behavior": "ignore" - } - } - }, - { - "extension": "revapi.filter", - "configuration": { - "elements": { - "exclude": [ - { - "matcher": "java", - "match": "@com.socketio4j.socketio.annotation.Internal ^*;" - } - ] - } - } - }, - { - "extension": "revapi.differences", - "configuration": { - "ignore": true, - "differences": [ - { - "code": "java.class.removed", - "regex": true, - "old": ".*com\\.socketio4j\\.socketio\\.(ack|handler|transport|messages|protocol|scheduler|misc|namespace|metrics|store\\.event)\\..*", - "justification": "Marked internal implementation classes with @Internal to define clean API boundaries" - }, - { - "code": "java.annotation.added", - "annotation": "@org.jetbrains.annotations.Nullable", - "justification": "Added nullability annotations for enhanced type safety and Kotlin interop" - }, - { - "code": "java.method.exception.checkedRemoved", - "justification": "Removing checked Exception makes listener methods easier to implement without boilerplate throws clause" - }, - { - "code": "java.method.removed", - "old": "method void com.socketio4j.socketio.handler.ClientHead::setLastBinaryPacket(com.socketio4j.socketio.protocol.Packet)", - "justification": "Internal binary packet handling moved to dedicated pipeline handler" - }, - { - "code": "java.method.addedToInterface", - "new": "method void com.socketio4j.socketio.listener.ClientListeners::removeConnectListener(com.socketio4j.socketio.listener.ConnectListener)", - "justification": "Added default method to allow dynamic unregistering of connect listeners" - }, - { - "code": "java.method.addedToInterface", - "new": "method void com.socketio4j.socketio.listener.ClientListeners::removeDisconnectListener(com.socketio4j.socketio.listener.DisconnectListener)", - "justification": "Added default method to allow dynamic unregistering of disconnect listeners" - }, - { - "code": "java.field.serialVersionUIDUnchanged", - "old": "field com.socketio4j.socketio.protocol.Packet.serialVersionUID", - "justification": "Packet serialization schema evolved; serialVersionUID maintained for backwards compatibility" - } - ] - } - } -] From bdfc54a0a4fa125f6e22ffc690d3dd7ad7366796 Mon Sep 17 00:00:00 2001 From: sanjomo Date: Wed, 23 Sep 2026 22:41:48 +0530 Subject: [PATCH 6/6] feat: stateful compatibility bridge for Packet engineIOVersion and dataSource --- .../socketio4j/socketio/protocol/Packet.java | 30 +++++++++++--- .../socketio/protocol/PacketTest.java | 40 ++++++++++++++----- 2 files changed, 56 insertions(+), 14 deletions(-) diff --git a/netty-socketio-core/src/main/java/com/socketio4j/socketio/protocol/Packet.java b/netty-socketio-core/src/main/java/com/socketio4j/socketio/protocol/Packet.java index 1e9dee94..0a0d8c06 100644 --- a/netty-socketio-core/src/main/java/com/socketio4j/socketio/protocol/Packet.java +++ b/netty-socketio-core/src/main/java/com/socketio4j/socketio/protocol/Packet.java @@ -30,6 +30,8 @@ public class Packet implements Serializable { private static final long serialVersionUID = 4560159536486711426L; private PacketType type; + @Deprecated + private EngineIOVersion engineIOVersion = EngineIOVersion.V4; private PacketType subType; private Long ackId; @@ -38,6 +40,8 @@ public class Packet implements Serializable { private Object data; + @Deprecated + private transient ByteBuf dataSource; private int attachmentsCount; private List attachments = Collections.emptyList(); @@ -56,6 +60,7 @@ public Packet(PacketType type) { @Deprecated public Packet(PacketType type, EngineIOVersion engineIOVersion) { this(type); + this.engineIOVersion = engineIOVersion; } public PacketType getSubType() { @@ -103,9 +108,11 @@ public Packet withNsp(String namespace) { Packet newPacket = new Packet(this.type); newPacket.setAckId(this.ackId); newPacket.setData(this.data); + newPacket.setDataSource(this.dataSource); newPacket.setName(this.name); newPacket.setSubType(this.subType); newPacket.setNsp(namespace); + newPacket.setEngineIOVersion(this.engineIOVersion); newPacket.attachments = this.attachments; newPacket.attachmentsCount = this.attachmentsCount; return newPacket; @@ -122,7 +129,20 @@ public Packet withNsp(String namespace) { */ @Deprecated public Packet withNsp(String namespace, EngineIOVersion engineIOVersion) { - return withNsp(namespace); + if (this.nsp.equalsIgnoreCase(namespace)) { + return this; + } else { + Packet newPacket = new Packet(this.type, engineIOVersion); + newPacket.setAckId(this.ackId); + newPacket.setData(this.data); + newPacket.setDataSource(this.dataSource); + newPacket.setName(this.name); + newPacket.setSubType(this.subType); + newPacket.setNsp(namespace); + newPacket.attachments = this.attachments; + newPacket.attachmentsCount = this.attachmentsCount; + return newPacket; + } } public void setNsp(String endpoint) { //patch for #903 @@ -179,7 +199,7 @@ public boolean isAttachmentsLoaded() { */ @Deprecated public EngineIOVersion getEngineIOVersion() { - return EngineIOVersion.V4; + return engineIOVersion; } /** @@ -187,7 +207,7 @@ public EngineIOVersion getEngineIOVersion() { */ @Deprecated public void setEngineIOVersion(EngineIOVersion engineIOVersion) { - // no-op: version is now negotiated per-connection + this.engineIOVersion = engineIOVersion; } /** @@ -195,7 +215,7 @@ public void setEngineIOVersion(EngineIOVersion engineIOVersion) { */ @Deprecated public ByteBuf getDataSource() { - return null; + return dataSource; } /** @@ -203,7 +223,7 @@ public ByteBuf getDataSource() { */ @Deprecated public void setDataSource(ByteBuf dataSource) { - // no-op: data source is handled via attachments/decoders + this.dataSource = dataSource; } @Override diff --git a/netty-socketio-core/src/test/java/com/socketio4j/socketio/protocol/PacketTest.java b/netty-socketio-core/src/test/java/com/socketio4j/socketio/protocol/PacketTest.java index b69d513d..eb738657 100644 --- a/netty-socketio-core/src/test/java/com/socketio4j/socketio/protocol/PacketTest.java +++ b/netty-socketio-core/src/test/java/com/socketio4j/socketio/protocol/PacketTest.java @@ -71,9 +71,16 @@ public void testPacketConstructorWithType() { @Test public void testPacketConstructorWithTypeAndEngineIOVersion() { - Packet packet = new Packet(PacketType.EVENT); - assertEquals(PacketType.EVENT, packet.getType()); - // assertEquals(EngineIOVersion.V4, packet.getEngineIOVersion()); + Packet packetDefault = new Packet(PacketType.EVENT); + assertEquals(PacketType.EVENT, packetDefault.getType()); + assertEquals(EngineIOVersion.V4, packetDefault.getEngineIOVersion()); + + Packet packetV3 = new Packet(PacketType.EVENT, EngineIOVersion.V3); + assertEquals(PacketType.EVENT, packetV3.getType()); + assertEquals(EngineIOVersion.V3, packetV3.getEngineIOVersion()); + + packetV3.setEngineIOVersion(EngineIOVersion.V4); + assertEquals(EngineIOVersion.V4, packetV3.getEngineIOVersion()); } @Test @@ -191,18 +198,18 @@ public void testPacketWithAllFields() { packet.setData("testData"); packet.setAckId(456L); packet.setNsp("/test"); - // packet.setDataSource(Unpooled.wrappedBuffer("source".getBytes())); + packet.setDataSource(Unpooled.wrappedBuffer("source".getBytes())); packet.initAttachments(1); packet.addAttachment(Unpooled.wrappedBuffer("attachment".getBytes())); assertEquals(PacketType.MESSAGE, packet.getType()); - // assertEquals(EngineIOVersion.V4, packet.getEngineIOVersion()); + assertEquals(EngineIOVersion.V4, packet.getEngineIOVersion()); assertEquals(PacketType.EVENT, packet.getSubType()); assertEquals("testEvent", packet.getName()); assertEquals("testData", packet.getData()); assertEquals(Long.valueOf(456), packet.getAckId()); assertEquals("/test", packet.getNsp()); - // assertNotNull(packet.getDataSource()); + assertNotNull(packet.getDataSource()); assertTrue(packet.hasAttachments()); assertTrue(packet.isAttachmentsLoaded()); assertEquals(1, packet.getAttachments().size()); @@ -226,7 +233,8 @@ public void testPacketCopyWithDifferentNamespace() { Object copiedData = copiedPacket.getData(); assertEquals(originalData, copiedData); assertSame(originalPacket.getAttachments(), copiedPacket.getAttachments()); - // assertSame(originalPacket.getDataSource(), copiedPacket.getDataSource()); + assertSame(originalPacket.getDataSource(), copiedPacket.getDataSource()); + assertEquals(originalPacket.getEngineIOVersion(), copiedPacket.getEngineIOVersion()); } @Test @@ -251,7 +259,8 @@ private void assertPacketCopied(Packet oldPacket, Packet newPacket) { Object oldData = oldPacket.getData(); Object newData = newPacket.getData(); assertEquals(oldData, newData); - // assertSame(oldPacket.getDataSource(), newPacket.getDataSource()); + assertSame(oldPacket.getDataSource(), newPacket.getDataSource()); + assertEquals(oldPacket.getEngineIOVersion(), newPacket.getEngineIOVersion()); } private Packet createPacket() { @@ -261,9 +270,22 @@ private Packet createPacket() { packet.setData("data"); packet.setAckId(1L); packet.setNsp("old"); - // packet.setDataSource(Unpooled.wrappedBuffer(new byte[]{10})); + packet.setDataSource(Unpooled.wrappedBuffer(new byte[]{10})); packet.initAttachments(1); packet.addAttachment(Unpooled.wrappedBuffer(new byte[]{20})); return packet; } + + @Test + public void testPacketCopyWithDifferentNamespaceAndEngineIOVersion() { + Packet originalPacket = createPacket(); + String newNamespace = "/newNamespace"; + + Packet copiedPacket = originalPacket.withNsp(newNamespace, EngineIOVersion.V3); + + assertEquals(newNamespace, copiedPacket.getNsp()); + assertNotSame(originalPacket, copiedPacket); + assertEquals(EngineIOVersion.V3, copiedPacket.getEngineIOVersion()); + assertSame(originalPacket.getDataSource(), copiedPacket.getDataSource()); + } } \ No newline at end of file