diff --git a/jetty-websocket/websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/autobahn/AutobahnTests.java b/jetty-websocket/websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/autobahn/AutobahnTests.java index 7a4b4232ba3..0346be14eb3 100644 --- a/jetty-websocket/websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/autobahn/AutobahnTests.java +++ b/jetty-websocket/websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/autobahn/AutobahnTests.java @@ -51,7 +51,7 @@ import org.testcontainers.utility.MountableFile; import static org.junit.jupiter.api.Assertions.assertTrue; -@Disabled +@Disabled("Disable this test so it doesn't run locally as it takes 1h+ to run.") @Testcontainers public class AutobahnTests { diff --git a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandler.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandler.java index 21c6e28a533..99cfd8bb2e6 100644 --- a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandler.java +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandler.java @@ -266,6 +266,10 @@ public class JavaxWebSocketFrameHandler implements FrameHandler { notifyOnClose(closeStatus, callback); container.notifySessionListeners((listener) -> listener.onJavaxWebSocketSessionClosed(session)); + + // Close AvailableEncoders and AvailableDecoders to call destroy() on any instances of Encoder/Encoder created. + session.getDecoders().close(); + session.getEncoders().close(); } private void notifyOnClose(CloseStatus closeStatus, Callback callback) diff --git a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/AvailableDecoders.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/AvailableDecoders.java index 4f89fd8d19a..8538262e148 100644 --- a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/AvailableDecoders.java +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/AvailableDecoders.java @@ -207,4 +207,9 @@ public class AvailableDecoders implements Iterable { return registeredDecoders.stream(); } + + public void close() + { + registeredDecoders.forEach(RegisteredDecoder::destroyInstance); + } } diff --git a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/RegisteredDecoder.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/RegisteredDecoder.java index be4d69ccbed..bc2b00b7249 100644 --- a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/RegisteredDecoder.java +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/RegisteredDecoder.java @@ -18,9 +18,13 @@ import javax.websocket.Decoder; import javax.websocket.EndpointConfig; import org.eclipse.jetty.websocket.javax.common.InitException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class RegisteredDecoder { + private static final Logger LOG = LoggerFactory.getLogger(RegisteredDecoder.class); + // The user supplied Decoder class public final Class decoder; // The javax.websocket.Decoder.* type (eg: Decoder.Binary, Decoder.BinaryStream, Decoder.Text, Decoder.TextStream) @@ -74,6 +78,23 @@ public class RegisteredDecoder return (T)instance; } + public void destroyInstance() + { + if (instance != null) + { + try + { + instance.destroy(); + } + catch (Throwable t) + { + LOG.warn("Error destroying Decoder", t); + } + + instance = null; + } + } + @Override public String toString() { diff --git a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/AvailableEncoders.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/AvailableEncoders.java index 3d351a90566..0da52610678 100644 --- a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/AvailableEncoders.java +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/AvailableEncoders.java @@ -28,9 +28,14 @@ import org.eclipse.jetty.websocket.core.exception.InvalidSignatureException; import org.eclipse.jetty.websocket.core.exception.InvalidWebSocketException; import org.eclipse.jetty.websocket.core.internal.util.ReflectUtils; import org.eclipse.jetty.websocket.javax.common.InitException; +import org.eclipse.jetty.websocket.javax.common.decoders.RegisteredDecoder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class AvailableEncoders implements Predicate> { + private static final Logger LOG = LoggerFactory.getLogger(RegisteredDecoder.class); + public static class RegisteredEncoder { public final Class encoder; @@ -62,6 +67,23 @@ public class AvailableEncoders implements Predicate> return objectType.isAssignableFrom(type); } + public void destroyInstance() + { + if (instance != null) + { + try + { + instance.destroy(); + } + catch (Throwable t) + { + LOG.warn("Error destroying Decoder", t); + } + + instance = null; + } + } + @Override public String toString() { @@ -286,4 +308,9 @@ public class AvailableEncoders implements Predicate> { return registeredEncoders.stream().anyMatch(registered -> registered.isType(type)); } + + public void close() + { + registeredEncoders.forEach(RegisteredEncoder::destroyInstance); + } } diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/EncoderLifeCycleTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/EncoderLifeCycleTest.java index 72acf34cc6d..d8b410d89a2 100644 --- a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/EncoderLifeCycleTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/EncoderLifeCycleTest.java @@ -37,7 +37,6 @@ import org.eclipse.jetty.websocket.javax.common.encoders.AvailableEncoders; import org.eclipse.jetty.websocket.javax.server.config.JavaxWebSocketServletContainerInitializer; import org.eclipse.jetty.websocket.javax.tests.EchoSocket; import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; import org.slf4j.Logger; @@ -147,8 +146,6 @@ public class EncoderLifeCycleTest } } - // TODO: Encoder.destroy() is never called in Jetty 10. - @Disabled() @ParameterizedTest @ValueSource(classes = {StringHolder.class, StringHolderSubtype.class}) public void testEncoderLifeCycle(Class clazz) throws Exception