This is an automated email from the ASF dual-hosted git repository. cshannon pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/activemq.git
commit bb5ccb4aaf4e5dee98186936eedef4433e56737c Author: Matt Pavlovich <[email protected]> AuthorDate: Tue Jul 14 08:52:22 2026 -0500 [AMQ-9359] Migrate Jetty EE9 -> EE11 - BOM: jetty-ee9-bom -> jetty-ee11-bom - Dropped artifacts with no EE11 equiv - WebSocket: the legacy WebSocketListener API is gone in EE11 - Security/TRACE: ee9.nested.ServletConstraint is gone; configureTraceMethod now uses the core immutable Constraint (FORBIDDEN/ALLOWED) via ee11.servlet.security. - ServletContextHandler: EE11 dropped the (Server, path, options) constructor - XML: WebAppContext ee9.webapp -> ee11.webapp --- activemq-amqp/pom.xml | 4 +- activemq-http/pom.xml | 12 ++--- .../transport/WebTransportServerSupport.java | 42 +++++++--------- .../discovery/http/EmbeddedJettyServer.java | 4 +- .../transport/http/HttpTransportServer.java | 11 +++-- .../activemq/transport/ws/WSTransportProxy.java | 31 +++++++----- .../activemq/transport/ws/WSTransportServer.java | 16 +++--- .../transport/ws/{jetty12 => ee11}/MQTTSocket.java | 26 ++++++---- .../ws/{jetty12 => ee11}/StompSocket.java | 22 +++++---- .../transport/ws/{jetty12 => ee11}/WSServlet.java | 18 +++---- .../apache/activemq/transport/ws/SocketTest.java | 8 +-- .../transport/ws/WSTransportProxyTest.java | 34 +++++++------ .../activemq/transport/ws/WSTransportTest.java | 4 +- activemq-web-console/pom.xml | 18 +++---- .../java/org/apache/activemq/web/tool/Main.java | 2 +- .../resources/jetty/jetty-activemq-console.xml | 2 +- .../src/test/resources/jetty/jetty-webapps.xml | 8 +-- activemq-web-demo/pom.xml | 8 +-- .../java/org/apache/activemq/web/JettyServer.java | 2 +- .../org/apache/activemq/web/JettyTestSupport.java | 2 +- activemq-web/pom.xml | 8 +-- .../org/apache/activemq/web/MessageServlet.java | 12 +++-- .../activemq/web/async/AsyncServletRequest.java | 7 ++- .../apache/activemq/web/config/JspConfigurer.java | 2 +- assembly/pom.xml | 57 ++++++++++------------ assembly/src/main/descriptors/common-bin.xml | 30 ++++++------ assembly/src/release/conf/jetty/jetty-webapps.xml | 20 ++++++-- pom.xml | 16 +++--- 28 files changed, 228 insertions(+), 198 deletions(-) diff --git a/activemq-amqp/pom.xml b/activemq-amqp/pom.xml index 91d06892e0..cba8c17d54 100644 --- a/activemq-amqp/pom.xml +++ b/activemq-amqp/pom.xml @@ -124,8 +124,8 @@ <!-- activemq-http's WSTransportServer uses the Jetty EE9 websocket ServletContainerInitializer; activemq-http declares it provided+optional, so the ws transport needs it at test runtime here. --> <dependency> - <groupId>org.eclipse.jetty.ee9.websocket</groupId> - <artifactId>jetty-ee9-websocket-jetty-server</artifactId> + <groupId>org.eclipse.jetty.ee11.websocket</groupId> + <artifactId>jetty-ee11-websocket-jetty-server</artifactId> <scope>test</scope> </dependency> <dependency> diff --git a/activemq-http/pom.xml b/activemq-http/pom.xml index cc578ca713..09780d541f 100644 --- a/activemq-http/pom.xml +++ b/activemq-http/pom.xml @@ -65,8 +65,8 @@ <artifactId>jetty-xml</artifactId> </dependency> <dependency> - <groupId>org.eclipse.jetty.ee9</groupId> - <artifactId>jetty-ee9-webapp</artifactId> + <groupId>org.eclipse.jetty.ee11</groupId> + <artifactId>jetty-ee11-webapp</artifactId> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> @@ -138,14 +138,14 @@ <optional>true</optional> </dependency> <dependency> - <groupId>org.eclipse.jetty.ee9.websocket</groupId> - <artifactId>jetty-ee9-websocket-jakarta-client</artifactId> + <groupId>org.eclipse.jetty.ee11.websocket</groupId> + <artifactId>jetty-ee11-websocket-jakarta-client</artifactId> <scope>provided</scope> <optional>true</optional> </dependency> <dependency> - <groupId>org.eclipse.jetty.ee9.websocket</groupId> - <artifactId>jetty-ee9-websocket-jetty-server</artifactId> + <groupId>org.eclipse.jetty.ee11.websocket</groupId> + <artifactId>jetty-ee11-websocket-jetty-server</artifactId> <scope>provided</scope> <optional>true</optional> </dependency> diff --git a/activemq-http/src/main/java/org/apache/activemq/transport/WebTransportServerSupport.java b/activemq-http/src/main/java/org/apache/activemq/transport/WebTransportServerSupport.java index be54eb1793..3fe4373ec3 100644 --- a/activemq-http/src/main/java/org/apache/activemq/transport/WebTransportServerSupport.java +++ b/activemq-http/src/main/java/org/apache/activemq/transport/WebTransportServerSupport.java @@ -23,9 +23,9 @@ import java.util.Map; import org.apache.activemq.util.InetAddressUtil; import org.apache.activemq.util.IntrospectionSupport; -import org.eclipse.jetty.ee9.nested.ServletConstraint; -import org.eclipse.jetty.ee9.security.ConstraintMapping; -import org.eclipse.jetty.ee9.security.ConstraintSecurityHandler; +import org.eclipse.jetty.ee11.servlet.security.ConstraintMapping; +import org.eclipse.jetty.ee11.servlet.security.ConstraintSecurityHandler; +import org.eclipse.jetty.security.Constraint; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.util.resource.ResourceFactory; @@ -111,27 +111,21 @@ abstract public class WebTransportServerSupport extends TransportServerSupport { protected void configureTraceMethod(ConstraintSecurityHandler securityHandler, boolean enableTrace) { - ServletConstraint servletConstraint = new ServletConstraint(); - servletConstraint.setName("trace-security"); - // If enableTrace is true we set authenticate=false so TRACE is permitted; otherwise - // authenticate=true forces authentication which - with no login service configured on this - // handler - forbids TRACE (403). Using the (name, role) constructor instead leaves - // authenticate=false, so the constraint would enforce nothing and TRACE would always pass. - servletConstraint.setAuthenticate(!enableTrace); - - ConstraintMapping mapping = new ConstraintMapping(); - mapping.setConstraint(servletConstraint); - mapping.setMethod("TRACE"); - mapping.setPathSpec("/"); - securityHandler.addConstraintMapping(mapping); - - servletConstraint = new ServletConstraint(); - servletConstraint.setName("allow"); - mapping = new ConstraintMapping(); - mapping.setConstraint(servletConstraint); - mapping.setMethodOmissions(new String[]{ "TRACE" }); - mapping.setPathSpec("/"); - securityHandler.addConstraintMapping(mapping); + // TRACE is disabled by default (Cross-Site Tracing protection). In EE11 the servlet-spec + // ServletConstraint is gone; ConstraintMapping takes the core immutable Constraint. A + // FORBIDDEN constraint on TRACE yields 403; ALLOWED serves it when explicitly enabled. + ConstraintMapping traceMapping = new ConstraintMapping(); + traceMapping.setConstraint(enableTrace ? Constraint.ALLOWED : Constraint.FORBIDDEN); + traceMapping.setMethod("TRACE"); + traceMapping.setPathSpec("/"); + securityHandler.addConstraintMapping(traceMapping); + + // All other methods are allowed. + ConstraintMapping allowMapping = new ConstraintMapping(); + allowMapping.setConstraint(Constraint.ALLOWED); + allowMapping.setMethodOmissions(new String[]{ "TRACE" }); + allowMapping.setPathSpec("/"); + securityHandler.addConstraintMapping(allowMapping); } public void setHttpOptions(Map<String, Object> options) { diff --git a/activemq-http/src/main/java/org/apache/activemq/transport/discovery/http/EmbeddedJettyServer.java b/activemq-http/src/main/java/org/apache/activemq/transport/discovery/http/EmbeddedJettyServer.java index 0c996292cf..0becd7fd70 100644 --- a/activemq-http/src/main/java/org/apache/activemq/transport/discovery/http/EmbeddedJettyServer.java +++ b/activemq-http/src/main/java/org/apache/activemq/transport/discovery/http/EmbeddedJettyServer.java @@ -19,8 +19,8 @@ package org.apache.activemq.transport.discovery.http; import java.net.URI; import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.ee9.servlet.ServletContextHandler; -import org.eclipse.jetty.ee9.servlet.ServletHolder; +import org.eclipse.jetty.ee11.servlet.ServletContextHandler; +import org.eclipse.jetty.ee11.servlet.ServletHolder; public class EmbeddedJettyServer implements org.apache.activemq.Service { diff --git a/activemq-http/src/main/java/org/apache/activemq/transport/http/HttpTransportServer.java b/activemq-http/src/main/java/org/apache/activemq/transport/http/HttpTransportServer.java index 4b354ceb76..97f6d9e65a 100644 --- a/activemq-http/src/main/java/org/apache/activemq/transport/http/HttpTransportServer.java +++ b/activemq-http/src/main/java/org/apache/activemq/transport/http/HttpTransportServer.java @@ -27,15 +27,15 @@ import org.apache.activemq.transport.WebTransportServerSupport; import org.apache.activemq.transport.util.TextWireFormat; import org.apache.activemq.transport.xstream.XStreamWireFormat; import org.apache.activemq.util.ServiceStopper; -import org.eclipse.jetty.ee9.security.ConstraintSecurityHandler; +import org.eclipse.jetty.ee11.servlet.security.ConstraintSecurityHandler; import org.eclipse.jetty.server.ConnectionFactory; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.HttpConnectionFactory; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Handler.Wrapper; -import org.eclipse.jetty.ee9.servlet.ServletContextHandler; -import org.eclipse.jetty.ee9.servlet.ServletHolder; +import org.eclipse.jetty.ee11.servlet.ServletContextHandler; +import org.eclipse.jetty.ee11.servlet.ServletHolder; public class HttpTransportServer extends WebTransportServerSupport { @@ -92,8 +92,11 @@ public class HttpTransportServer extends WebTransportServerSupport { URI boundTo = bind(); + // EE11 dropped the (Server, contextPath, options) constructor (no nested layer); create the + // context then set it as the server handler explicitly. ServletContextHandler contextHandler = - new ServletContextHandler(server, "/", ServletContextHandler.SECURITY); + new ServletContextHandler("/", ServletContextHandler.SECURITY); + server.setHandler(contextHandler); ServletHolder holder = new ServletHolder(); holder.setServlet(new HttpTunnelServlet()); diff --git a/activemq-http/src/main/java/org/apache/activemq/transport/ws/WSTransportProxy.java b/activemq-http/src/main/java/org/apache/activemq/transport/ws/WSTransportProxy.java index c981c72d98..90588588fa 100644 --- a/activemq-http/src/main/java/org/apache/activemq/transport/ws/WSTransportProxy.java +++ b/activemq-http/src/main/java/org/apache/activemq/transport/ws/WSTransportProxy.java @@ -34,8 +34,8 @@ import org.apache.activemq.util.IOExceptionSupport; import org.apache.activemq.util.IntrospectionSupport; import org.apache.activemq.util.ServiceStopper; import org.apache.activemq.wireformat.WireFormat; -import org.eclipse.jetty.ee9.websocket.api.Session; -import org.eclipse.jetty.ee9.websocket.api.WebSocketListener; +import org.eclipse.jetty.websocket.api.Callback; +import org.eclipse.jetty.websocket.api.Session; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,7 +43,7 @@ import org.slf4j.LoggerFactory; * A proxy class that manages sending WebSocket events to the wrapped protocol level * WebSocket Transport. */ -public final class WSTransportProxy extends TransportSupport implements Transport, WebSocketListener, BrokerServiceAware, WSTransportSink { +public final class WSTransportProxy extends TransportSupport implements Transport, Session.Listener.AutoDemanding, BrokerServiceAware, WSTransportSink { private static final Logger LOG = LoggerFactory.getLogger(WSTransportProxy.class); @@ -159,7 +159,7 @@ public final class WSTransportProxy extends TransportSupport implements Transpor //----- WebSocket methods being proxied to the WS Transport --------------// @Override - public void onWebSocketBinary(byte[] payload, int offset, int length) { + public void onWebSocketBinary(ByteBuffer payload, Callback callback) { if (!transportStartedAtLeastOnce()) { LOG.debug("Waiting for WebSocket to be properly started..."); try { @@ -171,8 +171,13 @@ public final class WSTransportProxy extends TransportSupport implements Transpor protocolLock.lock(); try { - wsTransport.onWebSocketBinary(ByteBuffer.wrap(payload, offset, length)); + // Copy the frame: Jetty may reuse the pooled buffer once the callback succeeds. + ByteBuffer copy = ByteBuffer.allocate(payload.remaining()); + copy.put(payload).flip(); + wsTransport.onWebSocketBinary(copy); + callback.succeed(); } catch (Exception e) { + callback.fail(e); onException(IOExceptionSupport.create(e)); } finally { protocolLock.unlock(); @@ -217,7 +222,7 @@ public final class WSTransportProxy extends TransportSupport implements Transpor } @Override - public void onWebSocketConnect(Session session) { + public void onWebSocketOpen(Session session) { this.session = session; this.session.setIdleTimeout(Duration.ZERO); @@ -245,10 +250,11 @@ public final class WSTransportProxy extends TransportSupport implements Transpor LOG.trace("WS Proxy sending string of size {} out", data.length()); try { - // FIXME: Convert to async API w/ tiemeout getDefaultSendTimeOut(), TimeUnit.SECONDS); - // Outbound text must be sent as a WebSocket TEXT frame (sendString), not a binary - // frame; sendString also encodes as UTF-8 per the WebSocket spec. - session.getRemote().sendString(data); + // Outbound text must be sent as a WebSocket TEXT frame (sendText), not a binary frame; + // sendText also encodes as UTF-8 per the WebSocket spec. Block with a timeout. + Callback.Completable callback = new Callback.Completable(); + session.sendText(data, callback); + callback.get(getDefaultSendTimeOut(), TimeUnit.SECONDS); } catch (Exception e) { throw IOExceptionSupport.create(e); } @@ -268,8 +274,9 @@ public final class WSTransportProxy extends TransportSupport implements Transpor LOG.trace("WS Proxy sending {} bytes out", data.remaining()); int limit = data.limit(); try { - // FIXME: Convert to async API w/ tiemeout getDefaultSendTimeOut(), TimeUnit.SECONDS); - session.getRemote().sendBytes(data); + Callback.Completable callback = new Callback.Completable(); + session.sendBinary(data, callback); + callback.get(getDefaultSendTimeOut(), TimeUnit.SECONDS); } catch (Exception e) { throw IOExceptionSupport.create(e); } diff --git a/activemq-http/src/main/java/org/apache/activemq/transport/ws/WSTransportServer.java b/activemq-http/src/main/java/org/apache/activemq/transport/ws/WSTransportServer.java index 4c7357a711..5b99a5f57c 100644 --- a/activemq-http/src/main/java/org/apache/activemq/transport/ws/WSTransportServer.java +++ b/activemq-http/src/main/java/org/apache/activemq/transport/ws/WSTransportServer.java @@ -26,17 +26,17 @@ import org.apache.activemq.broker.BrokerServiceAware; import org.apache.activemq.command.BrokerInfo; import org.apache.activemq.transport.SocketConnectorFactory; import org.apache.activemq.transport.WebTransportServerSupport; -import org.apache.activemq.transport.ws.jetty12.WSServlet; +import org.apache.activemq.transport.ws.ee11.WSServlet; import org.apache.activemq.util.IntrospectionSupport; import org.apache.activemq.util.ServiceStopper; import org.eclipse.jetty.server.ConnectionFactory; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.HttpConnectionFactory; import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.ee9.security.ConstraintSecurityHandler; -import org.eclipse.jetty.ee9.servlet.ServletContextHandler; -import org.eclipse.jetty.ee9.servlet.ServletHolder; -import org.eclipse.jetty.ee9.websocket.server.config.JettyWebSocketServletContainerInitializer; +import org.eclipse.jetty.ee11.servlet.security.ConstraintSecurityHandler; +import org.eclipse.jetty.ee11.servlet.ServletContextHandler; +import org.eclipse.jetty.ee11.servlet.ServletHolder; +import org.eclipse.jetty.ee11.websocket.server.config.JettyWebSocketServletContainerInitializer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -73,9 +73,11 @@ public class WSTransportServer extends WebTransportServerSupport implements Brok URI boundTo = bind(); + // EE11 dropped the (Server, contextPath, options) constructor (no nested layer); create the + // context then set it as the server handler explicitly. ServletContextHandler contextHandler = - new ServletContextHandler(server, "/", ServletContextHandler.SECURITY); - // server.setHandler(contextHandler); Future: Jetty 12 EE10 API change + new ServletContextHandler("/", ServletContextHandler.SECURITY); + server.setHandler(contextHandler); ServletHolder holder = new ServletHolder(); JettyWebSocketServletContainerInitializer.configure(contextHandler, null); diff --git a/activemq-http/src/main/java/org/apache/activemq/transport/ws/jetty12/MQTTSocket.java b/activemq-http/src/main/java/org/apache/activemq/transport/ws/ee11/MQTTSocket.java similarity index 84% rename from activemq-http/src/main/java/org/apache/activemq/transport/ws/jetty12/MQTTSocket.java rename to activemq-http/src/main/java/org/apache/activemq/transport/ws/ee11/MQTTSocket.java index 6e14b9ec37..64cfc5a1ea 100644 --- a/activemq-http/src/main/java/org/apache/activemq/transport/ws/jetty12/MQTTSocket.java +++ b/activemq-http/src/main/java/org/apache/activemq/transport/ws/ee11/MQTTSocket.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.activemq.transport.ws.jetty12; +package org.apache.activemq.transport.ws.ee11; import java.io.IOException; import java.nio.ByteBuffer; @@ -26,8 +26,8 @@ import org.apache.activemq.transport.mqtt.MQTTCodec; import org.apache.activemq.transport.ws.AbstractMQTTSocket; import org.apache.activemq.util.ByteSequence; import org.apache.activemq.util.IOExceptionSupport; -import org.eclipse.jetty.ee9.websocket.api.WebSocketListener; -import org.eclipse.jetty.ee9.websocket.api.Session; +import org.eclipse.jetty.websocket.api.Callback; +import org.eclipse.jetty.websocket.api.Session; import org.fusesource.hawtbuf.Buffer; import org.fusesource.hawtbuf.DataByteArrayInputStream; import org.fusesource.mqtt.codec.DISCONNECT; @@ -35,7 +35,7 @@ import org.fusesource.mqtt.codec.MQTTFrame; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class MQTTSocket extends AbstractMQTTSocket implements MQTTCodec.MQTTFrameSink, WebSocketListener { +public class MQTTSocket extends AbstractMQTTSocket implements MQTTCodec.MQTTFrameSink, Session.Listener.AutoDemanding { private static final Logger LOG = LoggerFactory.getLogger(MQTTSocket.class); @@ -55,9 +55,10 @@ public class MQTTSocket extends AbstractMQTTSocket implements MQTTCodec.MQTTFram public void sendToMQTT(MQTTFrame command) throws IOException { ByteSequence bytes = wireFormat.marshal(command); try { - //timeout after a period of time so we don't wait forever and hold the protocol lock - // FIXME: convert to async .get(getDefaultSendTimeOut(), TimeUnit.SECONDS) - session.getRemote().sendBytes(ByteBuffer.wrap(bytes.getData(), 0, bytes.getLength())); + // Block on the async send but time out so we don't wait forever holding the protocol lock. + Callback.Completable callback = new Callback.Completable(); + session.sendBinary(ByteBuffer.wrap(bytes.getData(), 0, bytes.getLength()), callback); + callback.get(getDefaultSendTimeOut(), TimeUnit.SECONDS); } catch (Exception e) { throw IOExceptionSupport.create(e); } @@ -73,7 +74,7 @@ public class MQTTSocket extends AbstractMQTTSocket implements MQTTCodec.MQTTFram //----- WebSocket.OnTextMessage callback handlers ------------------------// @Override - public void onWebSocketBinary(byte[] bytes, int offset, int length) { + public void onWebSocketBinary(ByteBuffer payload, Callback callback) { if (!transportStartedAtLeastOnce()) { LOG.debug("Waiting for MQTTSocket to be properly started..."); try { @@ -85,9 +86,14 @@ public class MQTTSocket extends AbstractMQTTSocket implements MQTTCodec.MQTTFram protocolLock.lock(); try { + int length = payload.remaining(); + byte[] bytes = new byte[length]; + payload.get(bytes); receiveCounter += length; - codec.parse(new DataByteArrayInputStream(new Buffer(bytes, offset, length)), length); + codec.parse(new DataByteArrayInputStream(new Buffer(bytes, 0, length)), length); + callback.succeed(); } catch (Exception e) { + callback.fail(e); onException(IOExceptionSupport.create(e)); } finally { protocolLock.unlock(); @@ -115,7 +121,7 @@ public class MQTTSocket extends AbstractMQTTSocket implements MQTTCodec.MQTTFram } @Override - public void onWebSocketConnect(Session session) { + public void onWebSocketOpen(Session session) { this.session = session; this.session.setIdleTimeout(Duration.ZERO); } diff --git a/activemq-http/src/main/java/org/apache/activemq/transport/ws/jetty12/StompSocket.java b/activemq-http/src/main/java/org/apache/activemq/transport/ws/ee11/StompSocket.java similarity index 80% rename from activemq-http/src/main/java/org/apache/activemq/transport/ws/jetty12/StompSocket.java rename to activemq-http/src/main/java/org/apache/activemq/transport/ws/ee11/StompSocket.java index 2a47a5156c..c486dd35f8 100644 --- a/activemq-http/src/main/java/org/apache/activemq/transport/ws/jetty12/StompSocket.java +++ b/activemq-http/src/main/java/org/apache/activemq/transport/ws/ee11/StompSocket.java @@ -14,9 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.activemq.transport.ws.jetty12; +package org.apache.activemq.transport.ws.ee11; import java.io.IOException; +import java.nio.ByteBuffer; import java.time.Duration; import java.util.concurrent.TimeUnit; @@ -24,15 +25,15 @@ import org.apache.activemq.transport.stomp.Stomp; import org.apache.activemq.transport.stomp.StompFrame; import org.apache.activemq.transport.ws.AbstractStompSocket; import org.apache.activemq.util.IOExceptionSupport; -import org.eclipse.jetty.ee9.websocket.api.Session; -import org.eclipse.jetty.ee9.websocket.api.WebSocketListener; +import org.eclipse.jetty.websocket.api.Callback; +import org.eclipse.jetty.websocket.api.Session; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Implements web socket and mediates between servlet and the broker */ -public class StompSocket extends AbstractStompSocket implements WebSocketListener { +public class StompSocket extends AbstractStompSocket implements Session.Listener.AutoDemanding { private static final Logger LOG = LoggerFactory.getLogger(StompSocket.class); @@ -47,9 +48,10 @@ public class StompSocket extends AbstractStompSocket implements WebSocketListene @Override public void sendToStomp(StompFrame command) throws IOException { try { - //timeout after a period of time so we don't wait forever and hold the protocol lock - // FIXME: convert to timeout async get(getDefaultSendTimeOut(), TimeUnit.SECONDS) - session.getRemote().sendString(getWireFormat().marshalToString(command)); + // Block on the async send but time out so we don't wait forever holding the protocol lock. + Callback.Completable callback = new Callback.Completable(); + session.sendText(getWireFormat().marshalToString(command), callback); + callback.get(getDefaultSendTimeOut(), TimeUnit.SECONDS); } catch (Exception e) { throw IOExceptionSupport.create(e); } @@ -65,7 +67,9 @@ public class StompSocket extends AbstractStompSocket implements WebSocketListene //----- WebSocketListener event callbacks --------------------------------// @Override - public void onWebSocketBinary(byte[] arg0, int arg1, int arg2) { + public void onWebSocketBinary(ByteBuffer payload, Callback callback) { + // STOMP over WebSocket uses text frames; ignore binary but release the frame. + callback.succeed(); } @Override @@ -85,7 +89,7 @@ public class StompSocket extends AbstractStompSocket implements WebSocketListene } @Override - public void onWebSocketConnect(Session session) { + public void onWebSocketOpen(Session session) { this.session = session; this.session.setIdleTimeout(Duration.ZERO); } diff --git a/activemq-http/src/main/java/org/apache/activemq/transport/ws/jetty12/WSServlet.java b/activemq-http/src/main/java/org/apache/activemq/transport/ws/ee11/WSServlet.java similarity index 92% rename from activemq-http/src/main/java/org/apache/activemq/transport/ws/jetty12/WSServlet.java rename to activemq-http/src/main/java/org/apache/activemq/transport/ws/ee11/WSServlet.java index 86183c8c4f..f39432143a 100644 --- a/activemq-http/src/main/java/org/apache/activemq/transport/ws/jetty12/WSServlet.java +++ b/activemq-http/src/main/java/org/apache/activemq/transport/ws/ee11/WSServlet.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.activemq.transport.ws.jetty12; +package org.apache.activemq.transport.ws.ee11; import java.io.IOException; import java.net.URI; @@ -38,12 +38,12 @@ import org.apache.activemq.transport.TransportAcceptListener; import org.apache.activemq.transport.TransportFactory; import org.apache.activemq.transport.util.HttpTransportUtils; import org.apache.activemq.transport.ws.WSTransportProxy; -import org.eclipse.jetty.ee9.websocket.api.WebSocketListener; -import org.eclipse.jetty.ee9.websocket.server.JettyServerUpgradeRequest; -import org.eclipse.jetty.ee9.websocket.server.JettyServerUpgradeResponse; -import org.eclipse.jetty.ee9.websocket.server.JettyWebSocketCreator; -import org.eclipse.jetty.ee9.websocket.server.JettyWebSocketServlet; -import org.eclipse.jetty.ee9.websocket.server.JettyWebSocketServletFactory; +import org.eclipse.jetty.websocket.api.Session; +import org.eclipse.jetty.ee11.websocket.server.JettyServerUpgradeRequest; +import org.eclipse.jetty.ee11.websocket.server.JettyServerUpgradeResponse; +import org.eclipse.jetty.ee11.websocket.server.JettyWebSocketCreator; +import org.eclipse.jetty.ee11.websocket.server.JettyWebSocketServlet; +import org.eclipse.jetty.ee11.websocket.server.JettyWebSocketServletFactory; /** * Handle connection upgrade requests and creates web sockets @@ -93,7 +93,7 @@ public class WSServlet extends JettyWebSocketServlet implements BrokerServiceAwa factory.setCreator(new JettyWebSocketCreator() { @Override public Object createWebSocket(JettyServerUpgradeRequest req, JettyServerUpgradeResponse resp) { - WebSocketListener socket; + Session.Listener socket; Protocol requestedProtocol = Protocol.UNKNOWN; // When no sub-protocol is requested we default to STOMP for legacy reasons. @@ -141,7 +141,7 @@ public class WSServlet extends JettyWebSocketServlet implements BrokerServiceAwa }); } - private WebSocketListener findWSTransport(JettyServerUpgradeRequest request, JettyServerUpgradeResponse response) { + private Session.Listener findWSTransport(JettyServerUpgradeRequest request, JettyServerUpgradeResponse response) { WSTransportProxy proxy = null; for (String subProtocol : request.getSubProtocols()) { diff --git a/activemq-http/src/test/java/org/apache/activemq/transport/ws/SocketTest.java b/activemq-http/src/test/java/org/apache/activemq/transport/ws/SocketTest.java index 9f2aecfc84..bc36c6347a 100644 --- a/activemq-http/src/test/java/org/apache/activemq/transport/ws/SocketTest.java +++ b/activemq-http/src/test/java/org/apache/activemq/transport/ws/SocketTest.java @@ -18,8 +18,8 @@ package org.apache.activemq.transport.ws; import static org.junit.Assert.assertEquals; -import org.apache.activemq.transport.ws.jetty12.MQTTSocket; -import org.apache.activemq.transport.ws.jetty12.StompSocket; +import org.apache.activemq.transport.ws.ee11.MQTTSocket; +import org.apache.activemq.transport.ws.ee11.StompSocket; import org.junit.Test; public class SocketTest { @@ -31,8 +31,8 @@ public class SocketTest { assertEquals("ws://localhost:8080", stompSocketJetty8.getRemoteAddress()); - org.apache.activemq.transport.ws.jetty12.StompSocket stompSocketJetty11 = - new org.apache.activemq.transport.ws.jetty12.StompSocket("ws://localhost:8080"); + org.apache.activemq.transport.ws.ee11.StompSocket stompSocketJetty11 = + new org.apache.activemq.transport.ws.ee11.StompSocket("ws://localhost:8080"); assertEquals("ws://localhost:8080", stompSocketJetty11.getRemoteAddress()); } diff --git a/activemq-http/src/test/java/org/apache/activemq/transport/ws/WSTransportProxyTest.java b/activemq-http/src/test/java/org/apache/activemq/transport/ws/WSTransportProxyTest.java index 1fa58538ac..4ed505eccd 100644 --- a/activemq-http/src/test/java/org/apache/activemq/transport/ws/WSTransportProxyTest.java +++ b/activemq-http/src/test/java/org/apache/activemq/transport/ws/WSTransportProxyTest.java @@ -17,7 +17,8 @@ package org.apache.activemq.transport.ws; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; @@ -29,14 +30,14 @@ import java.nio.charset.StandardCharsets; import org.apache.activemq.transport.Transport; import org.apache.activemq.transport.TransportListener; -import org.eclipse.jetty.ee9.websocket.api.RemoteEndpoint; -import org.eclipse.jetty.ee9.websocket.api.Session; +import org.eclipse.jetty.websocket.api.Callback; +import org.eclipse.jetty.websocket.api.Session; import org.junit.Test; /** * Unit tests for {@link WSTransportProxy} frame handling. In particular that outbound * text is emitted as a WebSocket TEXT frame and outbound binary as a BINARY frame - - * a regression guard: outbound text was previously sent via sendBytes (a binary frame). + * a regression guard: outbound text was previously sent as a binary frame. */ public class WSTransportProxyTest { @@ -46,8 +47,8 @@ public class WSTransportProxyTest { WSTransportProxy proxy = new WSTransportProxy("ws://localhost:61614", transport); proxy.setTransportListener(mock(TransportListener.class)); - proxy.start(); // counts down the "started" latch so sends don't block - proxy.onWebSocketConnect(session); // installs the session used by the outbound sends + proxy.start(); // counts down the "started" latch so sends don't block + proxy.onWebSocketOpen(session); // installs the session used by the outbound sends return proxy; } @@ -55,32 +56,33 @@ public class WSTransportProxyTest { public void testOutboundTextIsSentAsTextFrame() throws Exception { WSTransport wsTransport = mock(WSTransport.class); Session session = mock(Session.class); - RemoteEndpoint remote = mock(RemoteEndpoint.class); - when(session.getRemote()).thenReturn(remote); + // The proxy blocks on the send callback, so complete it when sendText is invoked. + doAnswer(inv -> { inv.getArgument(1, Callback.class).succeed(); return null; }) + .when(session).sendText(any(), any(Callback.class)); WSTransportProxy proxy = startedProxy(wsTransport, session); proxy.onSocketOutboundText("CONNECTED\n"); - // Must be a WebSocket TEXT frame (sendString), never a binary frame. - verify(remote, times(1)).sendString("CONNECTED\n"); - verify(remote, never()).sendBytes(any(ByteBuffer.class)); + // Must be a WebSocket TEXT frame (sendText), never a binary frame. + verify(session, times(1)).sendText(eq("CONNECTED\n"), any(Callback.class)); + verify(session, never()).sendBinary(any(ByteBuffer.class), any(Callback.class)); } @Test public void testOutboundBinaryIsSentAsBinaryFrame() throws Exception { WSTransport wsTransport = mock(WSTransport.class); Session session = mock(Session.class); - RemoteEndpoint remote = mock(RemoteEndpoint.class); - when(session.getRemote()).thenReturn(remote); + doAnswer(inv -> { inv.getArgument(1, Callback.class).succeed(); return null; }) + .when(session).sendBinary(any(ByteBuffer.class), any(Callback.class)); WSTransportProxy proxy = startedProxy(wsTransport, session); ByteBuffer payload = ByteBuffer.wrap("frame-bytes".getBytes(StandardCharsets.UTF_8)); proxy.onSocketOutboundBinary(payload); - // Must be a WebSocket BINARY frame (sendBytes), never a text frame. - verify(remote, times(1)).sendBytes(any(ByteBuffer.class)); - verify(remote, never()).sendString(anyString()); + // Must be a WebSocket BINARY frame (sendBinary), never a text frame. + verify(session, times(1)).sendBinary(any(ByteBuffer.class), any(Callback.class)); + verify(session, never()).sendText(any(), any(Callback.class)); } } diff --git a/activemq-http/src/test/java/org/apache/activemq/transport/ws/WSTransportTest.java b/activemq-http/src/test/java/org/apache/activemq/transport/ws/WSTransportTest.java index 870f35c930..af13166afd 100644 --- a/activemq-http/src/test/java/org/apache/activemq/transport/ws/WSTransportTest.java +++ b/activemq-http/src/test/java/org/apache/activemq/transport/ws/WSTransportTest.java @@ -42,7 +42,7 @@ import org.eclipse.jetty.io.ClientConnector; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.util.ssl.SslContextFactory; -import org.eclipse.jetty.ee9.webapp.WebAppContext; +import org.eclipse.jetty.ee11.webapp.WebAppContext; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -74,7 +74,7 @@ public class WSTransportTest extends WSTransportTestSupport { Connector connector = createJettyConnector(server); WebAppContext context = new WebAppContext(); - context.setResourceBase("src/test/webapp"); + context.setBaseResourceAsString("src/test/webapp"); context.setContextPath("/"); context.setServer(server); diff --git a/activemq-web-console/pom.xml b/activemq-web-console/pom.xml index fe74be93aa..65f2e6f7ec 100644 --- a/activemq-web-console/pom.xml +++ b/activemq-web-console/pom.xml @@ -52,8 +52,8 @@ </configuration> </plugin> <plugin> - <groupId>org.eclipse.jetty.ee9</groupId> - <artifactId>jetty-ee9-maven-plugin</artifactId> + <groupId>org.eclipse.jetty.ee11</groupId> + <artifactId>jetty-ee11-maven-plugin</artifactId> <version>${jetty-version}</version> <configuration> <httpConnector> @@ -242,8 +242,8 @@ <!-- web container --> <dependency> - <groupId>org.eclipse.jetty.ee9</groupId> - <artifactId>jetty-ee9-webapp</artifactId> + <groupId>org.eclipse.jetty.ee11</groupId> + <artifactId>jetty-ee11-webapp</artifactId> <scope>provided</scope> </dependency> <dependency> @@ -280,15 +280,15 @@ <!-- JSTL support --> <dependency> - <groupId>org.eclipse.jetty.ee9</groupId> - <artifactId>jetty-ee9-glassfish-jstl</artifactId> + <groupId>org.eclipse.jetty.ee11</groupId> + <artifactId>jetty-ee11-glassfish-jstl</artifactId> <scope>provided</scope> </dependency> <!-- Tag Libs --> <!-- These two should be available either in the WAR itself or from the container. We can't configure - jetty-ee9-maven-plugin with <useProvidedScope>true</useProvidedScope> because we don't need ALL provided + jetty-ee11-maven-plugin with <useProvidedScope>true</useProvidedScope> because we don't need ALL provided dependencies. But we shouldn't build the WAR with these two included either, because _full_ web container may provide own taglibs... Not me to decide ;) --> @@ -338,8 +338,8 @@ </dependency> <dependency> - <groupId>org.eclipse.jetty.ee9</groupId> - <artifactId>jetty-ee9-apache-jsp</artifactId> + <groupId>org.eclipse.jetty.ee11</groupId> + <artifactId>jetty-ee11-apache-jsp</artifactId> <scope>provided</scope> <exclusions> <exclusion> diff --git a/activemq-web-console/src/test/java/org/apache/activemq/web/tool/Main.java b/activemq-web-console/src/test/java/org/apache/activemq/web/tool/Main.java index 1f06c789ad..d95a6ffb81 100644 --- a/activemq-web-console/src/test/java/org/apache/activemq/web/tool/Main.java +++ b/activemq-web-console/src/test/java/org/apache/activemq/web/tool/Main.java @@ -22,7 +22,7 @@ import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.ContextHandlerCollection; import org.eclipse.jetty.util.resource.ResourceFactory; -import org.eclipse.jetty.ee9.webapp.WebAppContext; +import org.eclipse.jetty.ee11.webapp.WebAppContext; /** * A simple bootstrap class for starting Jetty in your IDE using the local web diff --git a/activemq-web-console/src/test/resources/jetty/jetty-activemq-console.xml b/activemq-web-console/src/test/resources/jetty/jetty-activemq-console.xml index 05512ba298..8e138b9e79 100644 --- a/activemq-web-console/src/test/resources/jetty/jetty-activemq-console.xml +++ b/activemq-web-console/src/test/resources/jetty/jetty-activemq-console.xml @@ -16,7 +16,7 @@ limitations under the License. --> <!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_12_0.dtd"> -<Configure class="org.eclipse.jetty.ee9.webapp.WebAppContext"> +<Configure class="org.eclipse.jetty.ee11.webapp.WebAppContext"> <Set name="contextPath">/console</Set> <Set name="resourceBase">webapps/admin</Set> </Configure> \ No newline at end of file diff --git a/activemq-web-console/src/test/resources/jetty/jetty-webapps.xml b/activemq-web-console/src/test/resources/jetty/jetty-webapps.xml index c1ccff6965..03b9f29241 100644 --- a/activemq-web-console/src/test/resources/jetty/jetty-webapps.xml +++ b/activemq-web-console/src/test/resources/jetty/jetty-webapps.xml @@ -86,7 +86,7 @@ <!-- Admin Web Application --> <Call name="addHandler"> <Arg> - <New class="org.eclipse.jetty.ee9.webapp.WebAppContext"> + <New class="org.eclipse.jetty.ee11.webapp.WebAppContext"> <Set name="contextPath">/admin</Set> <Set name="baseResourceAsString">src/test/resources/webapps/admin</Set> <Set name="logUrlOnStart">true</Set> @@ -94,7 +94,7 @@ runs and TLDs are discovered (otherwise JSP compilation fails with a null TldCache). --> <Call name="setAttribute"> <Arg>org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern</Arg> - <Arg>.*/jetty-ee9-[^/]*\.jar$|.*/jetty-jakarta-servlet-api-[^/]*\.jar$|.*/jakarta\.servlet\.jsp\.jstl.*\.jar$</Arg> + <Arg>.*/jetty-ee11-[^/]*\.jar$|.*/jetty-jakarta-servlet-api-[^/]*\.jar$|.*/jakarta\.servlet\.jsp\.jstl.*\.jar$</Arg> </Call> </New> </Arg> @@ -103,7 +103,7 @@ <!-- API Web Application --> <Call name="addHandler"> <Arg> - <New class="org.eclipse.jetty.ee9.webapp.WebAppContext"> + <New class="org.eclipse.jetty.ee11.webapp.WebAppContext"> <Set name="contextPath">/api</Set> <Set name="baseResourceAsString">src/test/resources/webapps/api</Set> <Set name="logUrlOnStart">true</Set> @@ -111,7 +111,7 @@ runs and TLDs are discovered (otherwise JSP compilation fails with a null TldCache). --> <Call name="setAttribute"> <Arg>org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern</Arg> - <Arg>.*/jetty-ee9-[^/]*\.jar$|.*/jetty-jakarta-servlet-api-[^/]*\.jar$|.*/jakarta\.servlet\.jsp\.jstl.*\.jar$</Arg> + <Arg>.*/jetty-ee11-[^/]*\.jar$|.*/jetty-jakarta-servlet-api-[^/]*\.jar$|.*/jakarta\.servlet\.jsp\.jstl.*\.jar$</Arg> </Call> </New> </Arg> diff --git a/activemq-web-demo/pom.xml b/activemq-web-demo/pom.xml index d8c59dc766..378c2d5d84 100644 --- a/activemq-web-demo/pom.xml +++ b/activemq-web-demo/pom.xml @@ -33,8 +33,8 @@ <build> <plugins> <plugin> - <groupId>org.eclipse.jetty.ee9</groupId> - <artifactId>jetty-ee9-maven-plugin</artifactId> + <groupId>org.eclipse.jetty.ee11</groupId> + <artifactId>jetty-ee11-maven-plugin</artifactId> <configuration> <httpConnector> <port>${jetty.port}</port> @@ -188,8 +188,8 @@ <scope>test</scope> </dependency> <dependency> - <groupId>org.eclipse.jetty.ee9</groupId> - <artifactId>jetty-ee9-webapp</artifactId> + <groupId>org.eclipse.jetty.ee11</groupId> + <artifactId>jetty-ee11-webapp</artifactId> <scope>test</scope> </dependency> <dependency> diff --git a/activemq-web-demo/src/test/java/org/apache/activemq/web/JettyServer.java b/activemq-web-demo/src/test/java/org/apache/activemq/web/JettyServer.java index eb5602eb04..50b074e78d 100644 --- a/activemq-web-demo/src/test/java/org/apache/activemq/web/JettyServer.java +++ b/activemq-web-demo/src/test/java/org/apache/activemq/web/JettyServer.java @@ -23,7 +23,7 @@ import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.util.resource.ResourceFactory; -import org.eclipse.jetty.ee9.webapp.WebAppContext; +import org.eclipse.jetty.ee11.webapp.WebAppContext; /** * A simple bootstrap class for starting Jetty in your IDE using the local web diff --git a/activemq-web-demo/src/test/java/org/apache/activemq/web/JettyTestSupport.java b/activemq-web-demo/src/test/java/org/apache/activemq/web/JettyTestSupport.java index 7fd016d15e..f5efc2e8e8 100644 --- a/activemq-web-demo/src/test/java/org/apache/activemq/web/JettyTestSupport.java +++ b/activemq-web-demo/src/test/java/org/apache/activemq/web/JettyTestSupport.java @@ -37,7 +37,7 @@ import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.util.resource.ResourceFactory; -import org.eclipse.jetty.ee9.webapp.WebAppContext; +import org.eclipse.jetty.ee11.webapp.WebAppContext; import org.junit.After; import org.junit.Before; import org.slf4j.Logger; diff --git a/activemq-web/pom.xml b/activemq-web/pom.xml index 4f67b91687..17303133b9 100644 --- a/activemq-web/pom.xml +++ b/activemq-web/pom.xml @@ -79,12 +79,12 @@ <scope>provided</scope> </dependency> <dependency> - <groupId>org.eclipse.jetty.ee9</groupId> - <artifactId>jetty-ee9-webapp</artifactId> + <groupId>org.eclipse.jetty.ee11</groupId> + <artifactId>jetty-ee11-webapp</artifactId> </dependency> <dependency> - <groupId>org.eclipse.jetty.ee9.websocket</groupId> - <artifactId>jetty-ee9-websocket-jetty-server</artifactId> + <groupId>org.eclipse.jetty.ee11.websocket</groupId> + <artifactId>jetty-ee11-websocket-jetty-server</artifactId> </dependency> <!-- Just used for testing --> diff --git a/activemq-web/src/main/java/org/apache/activemq/web/MessageServlet.java b/activemq-web/src/main/java/org/apache/activemq/web/MessageServlet.java index 10675a7cf2..dd1ac3ee4b 100644 --- a/activemq-web/src/main/java/org/apache/activemq/web/MessageServlet.java +++ b/activemq-web/src/main/java/org/apache/activemq/web/MessageServlet.java @@ -18,6 +18,7 @@ package org.apache.activemq.web; import jakarta.jms.*; +import jakarta.servlet.DispatcherType; import jakarta.servlet.ServletConfig; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; @@ -189,11 +190,12 @@ public class MessageServlet extends MessageServletSupport { throw new NoDestinationSuppliedException(); } consumer = (MessageAvailableConsumer) client.getConsumer(destination, request.getHeader(WebClient.selectorName)); - final AsyncServletRequest asyncRequest = AsyncServletRequest.getAsyncRequest(request); - - // Don't allow concurrent use of the consumer. Do make sure to allow - // subsequent calls on asyncRequest to use the consumer. - if (asyncRequest.isInitial() && !activeConsumers.add(consumer)) { + // Don't allow concurrent use of the consumer on the initial dispatch. Subsequent async + // re-dispatches (DispatcherType.ASYNC) reuse the already-registered consumer. Determine + // "initial" from the CURRENT request: EE11 does not update the stored original request's + // dispatcher type on an async re-dispatch (EE9 reused the same request object), so + // AsyncServletRequest.isInitial() would wrongly report true on re-dispatch. + if (request.getDispatcherType() != DispatcherType.ASYNC && !activeConsumers.add(consumer)) { throw new ServletException("Concurrent access to consumer is not supported"); } diff --git a/activemq-web/src/main/java/org/apache/activemq/web/async/AsyncServletRequest.java b/activemq-web/src/main/java/org/apache/activemq/web/async/AsyncServletRequest.java index 4ba158b456..9a207a79a9 100644 --- a/activemq-web/src/main/java/org/apache/activemq/web/async/AsyncServletRequest.java +++ b/activemq-web/src/main/java/org/apache/activemq/web/async/AsyncServletRequest.java @@ -114,9 +114,12 @@ public class AsyncServletRequest implements AsyncListener { LOG.debug("ActiveMQAsyncRequest " + event + " timeout."); } + // Use the context's request/response rather than event.getSuppliedRequest(): the listener + // is registered via addListener(this) (no supplied request/response), so getSuppliedRequest() + // is null under EE11's spec-compliant behavior (EE9 happened to populate it). final AsyncContext context = event.getAsyncContext(); - if (context != null && event.getSuppliedRequest().isAsyncStarted()) { - // We must call dispatch to finish the request on timeout. + if (context != null && context.getRequest().isAsyncStarted()) { + // We must call dispatch to finish the request on timeout, // then set the status code to prevent a 500 error. context.dispatch(); final ServletResponse response = context.getResponse(); diff --git a/activemq-web/src/main/java/org/apache/activemq/web/config/JspConfigurer.java b/activemq-web/src/main/java/org/apache/activemq/web/config/JspConfigurer.java index 6fe6d53779..290925e893 100644 --- a/activemq-web/src/main/java/org/apache/activemq/web/config/JspConfigurer.java +++ b/activemq-web/src/main/java/org/apache/activemq/web/config/JspConfigurer.java @@ -19,7 +19,7 @@ package org.apache.activemq.web.config; import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Handler.Sequence; -import org.eclipse.jetty.ee9.webapp.WebAppContext; +import org.eclipse.jetty.ee11.webapp.WebAppContext; /** * diff --git a/assembly/pom.xml b/assembly/pom.xml index 42785a7f94..c84c62a473 100644 --- a/assembly/pom.xml +++ b/assembly/pom.xml @@ -379,24 +379,16 @@ <artifactId>jettison</artifactId> </dependency> <dependency> - <groupId>org.eclipse.jetty.ee9</groupId> - <artifactId>jetty-ee9-webapp</artifactId> + <groupId>org.eclipse.jetty.ee11</groupId> + <artifactId>jetty-ee11-webapp</artifactId> </dependency> <dependency> - <groupId>org.eclipse.jetty.ee9</groupId> - <artifactId>jetty-ee9-annotations</artifactId> + <groupId>org.eclipse.jetty.ee11</groupId> + <artifactId>jetty-ee11-annotations</artifactId> </dependency> <dependency> - <groupId>org.eclipse.jetty.ee9</groupId> - <artifactId>jetty-ee9-nested</artifactId> - </dependency> - <dependency> - <groupId>org.eclipse.jetty.ee9</groupId> - <artifactId>jetty-ee9-security</artifactId> - </dependency> - <dependency> - <groupId>org.eclipse.jetty.ee9</groupId> - <artifactId>jetty-ee9-servlet</artifactId> + <groupId>org.eclipse.jetty.ee11</groupId> + <artifactId>jetty-ee11-servlet</artifactId> </dependency> <dependency> <groupId>org.eclipse.jetty.ee</groupId> @@ -454,24 +446,20 @@ <artifactId>jetty-websocket-jetty-api</artifactId> </dependency> <dependency> - <groupId>org.eclipse.jetty.ee9.websocket</groupId> - <artifactId>jetty-ee9-websocket-jakarta-client</artifactId> - </dependency> - <dependency> - <groupId>org.eclipse.jetty.ee9.websocket</groupId> - <artifactId>jetty-ee9-websocket-jetty-api</artifactId> + <groupId>org.eclipse.jetty.ee11.websocket</groupId> + <artifactId>jetty-ee11-websocket-jakarta-client</artifactId> </dependency> <dependency> - <groupId>org.eclipse.jetty.ee9.websocket</groupId> - <artifactId>jetty-ee9-websocket-jetty-common</artifactId> + <groupId>org.eclipse.jetty.websocket</groupId> + <artifactId>jetty-websocket-jetty-common</artifactId> </dependency> <dependency> - <groupId>org.eclipse.jetty.ee9.websocket</groupId> - <artifactId>jetty-ee9-websocket-jetty-server</artifactId> + <groupId>org.eclipse.jetty.ee11.websocket</groupId> + <artifactId>jetty-ee11-websocket-jetty-server</artifactId> </dependency> <dependency> - <groupId>org.eclipse.jetty.ee9.websocket</groupId> - <artifactId>jetty-ee9-websocket-servlet</artifactId> + <groupId>org.eclipse.jetty.ee11.websocket</groupId> + <artifactId>jetty-ee11-websocket-servlet</artifactId> </dependency> <!-- o 'org.eclipse.jetty.websocket:websocket-core-common' @@ -527,18 +515,27 @@ o 'org.eclipse.jetty:apache-jsp' </dependency> <dependency> - <groupId>org.eclipse.jetty.ee9</groupId> - <artifactId>jetty-ee9-apache-jsp</artifactId> + <groupId>org.eclipse.jetty.ee11</groupId> + <artifactId>jetty-ee11-apache-jsp</artifactId> </dependency> <dependency> - <groupId>org.eclipse.jetty.ee9</groupId> - <artifactId>jetty-ee9-glassfish-jstl</artifactId> + <groupId>org.eclipse.jetty.ee11</groupId> + <artifactId>jetty-ee11-glassfish-jstl</artifactId> </dependency> <dependency> <groupId>jakarta.servlet.jsp.jstl</groupId> <artifactId>jakarta.servlet.jsp.jstl-api</artifactId> <version>3.0.2</version> </dependency> + <dependency> + <groupId>jakarta.el</groupId> + <artifactId>jakarta.el-api</artifactId> + <version>6.0.1</version> + </dependency> + <dependency> + <groupId>jakarta.servlet.jsp</groupId> + <artifactId>jakarta.servlet.jsp-api</artifactId> + </dependency> <dependency> <groupId>org.glassfish.web</groupId> <artifactId>jakarta.servlet.jsp.jstl</artifactId> diff --git a/assembly/src/main/descriptors/common-bin.xml b/assembly/src/main/descriptors/common-bin.xml index e99cba79bb..d6a945e4ba 100644 --- a/assembly/src/main/descriptors/common-bin.xml +++ b/assembly/src/main/descriptors/common-bin.xml @@ -272,38 +272,36 @@ <include>org.eclipse.jetty:jetty-plus</include> <include>org.eclipse.jetty:jetty-security</include> <include>org.eclipse.jetty:jetty-rewrite</include> - <include>org.eclipse.jetty.ee9:jetty-ee9-nested</include> - <include>org.eclipse.jetty.ee9:jetty-ee9-security</include> - <include>org.eclipse.jetty.ee9:jetty-ee9-servlet</include> - <include>org.eclipse.jetty.ee9:jetty-ee9-webapp</include> + <include>org.eclipse.jetty.ee11:jetty-ee11-servlet</include> + <include>org.eclipse.jetty.ee11:jetty-ee11-webapp</include> <!-- plus + annotations enable ServletContainerInitializer/TLD scanning (JSP/JSTL) --> - <include>org.eclipse.jetty.ee9:jetty-ee9-plus</include> + <include>org.eclipse.jetty.ee11:jetty-ee11-plus</include> <include>org.eclipse.jetty:jetty-annotations</include> - <include>org.eclipse.jetty.ee9:jetty-ee9-annotations</include> - <include>org.eclipse.jetty.ee9:jetty-ee9-apache-jsp</include> - <include>org.eclipse.jetty.toolchain:jetty-jakarta-servlet-api</include> + <include>org.eclipse.jetty.ee11:jetty-ee11-annotations</include> + <include>org.eclipse.jetty.ee11:jetty-ee11-apache-jsp</include> + <include>jakarta.servlet:jakarta.servlet-api</include> <include>org.eclipse.jetty.websocket:jetty-websocket-core-client</include> <include>org.eclipse.jetty.websocket:jetty-websocket-core-common</include> <include>org.eclipse.jetty.websocket:jetty-websocket-core-server</include> <include>org.eclipse.jetty.websocket:jetty-websocket-jetty-client</include> <include>org.eclipse.jetty.websocket:jetty-websocket-jetty-api</include> <include>org.eclipse.jetty.orbit:javax.security.auth.message</include> - <include>org.eclipse.jetty.ee9.websocket:jetty-ee9-websocket-jakarta-client</include> - <include>org.eclipse.jetty.ee9.websocket:jetty-ee9-websocket-jetty-api</include> - <include>org.eclipse.jetty.ee9.websocket:jetty-ee9-websocket-jetty-common</include> - <include>org.eclipse.jetty.ee9.websocket:jetty-ee9-websocket-jetty-server</include> - <include>org.eclipse.jetty.ee9.websocket:jetty-ee9-websocket-servlet</include> - <!-- include>jakarta.servlet:jakarta.servlet-api</include --> + <include>org.eclipse.jetty.ee11.websocket:jetty-ee11-websocket-jakarta-client</include> + <include>org.eclipse.jetty.websocket:jetty-websocket-jetty-common</include> + <include>org.eclipse.jetty.ee11.websocket:jetty-ee11-websocket-jetty-server</include> + <include>org.eclipse.jetty.ee11.websocket:jetty-ee11-websocket-servlet</include> <include>jakarta.websocket:jakarta.websocket-api</include> <!-- JSP support --> - <!-- Jetty JSP impl (pulled in via jetty-ee9-apache-jsp) --> + <!-- Jetty JSP impl (pulled in via jetty-ee11-apache-jsp) --> + <include>jakarta.servlet.jsp:jakarta.servlet.jsp-api</include> <include>org.mortbay.jasper:mortbay-apache-jsp</include> <!-- jstl and el api --> - <include>org.eclipse.jetty.ee9:jetty-ee9-glassfish-jstl</include> + <include>org.eclipse.jetty.ee11:jetty-ee11-glassfish-jstl</include> <include>jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api</include> <include>org.glassfish.web:jakarta.servlet.jsp.jstl</include> <!-- include>org.apache.taglibs:taglibs-standard-spec</include --> <!-- jstl and el impl --> + <include>jakarta.el:jakarta.el-api</include> <include>org.mortbay.jasper:mortbay-apache-el</include> <!-- include>org.apache.taglibs:taglibs-standard-impl</include --> diff --git a/assembly/src/release/conf/jetty/jetty-webapps.xml b/assembly/src/release/conf/jetty/jetty-webapps.xml index 52e94fc08c..f4bd9603d3 100644 --- a/assembly/src/release/conf/jetty/jetty-webapps.xml +++ b/assembly/src/release/conf/jetty/jetty-webapps.xml @@ -134,7 +134,7 @@ <!-- Admin Web Application --> <Call name="addHandler"> <Arg> - <New class="org.eclipse.jetty.ee9.webapp.WebAppContext"> + <New class="org.eclipse.jetty.ee11.webapp.WebAppContext"> <Set name="contextPath">/admin</Set> <Set name="baseResourceAsString"><Property name="activemq.home" default="."/>/webapps/admin</Set> <Set name="logUrlOnStart">true</Set> @@ -142,7 +142,13 @@ runs and TLDs are discovered (otherwise JSP compilation fails with a null TldCache). --> <Call name="setAttribute"> <Arg>org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern</Arg> - <Arg>.*/jetty-ee9-[^/]*\.jar$|.*/jetty-jakarta-servlet-api-[^/]*\.jar$|.*/jakarta\.servlet\.jsp\.jstl.*\.jar$</Arg> + <Arg>.*/jetty-ee11-[^/]*\.jar$|.*/jakarta\.servlet-api-[^/]*\.jar$|.*/jakarta\.servlet\.jsp\.jstl.*\.jar$</Arg> + </Call> + <!-- Jasper needs an InstanceManager in the ServletContext to instantiate JSP/tag classes. + EE11 no longer wires one for a plain exploded WebAppContext, so set a simple one. --> + <Call name="setAttribute"> + <Arg>org.apache.tomcat.InstanceManager</Arg> + <Arg><New class="org.apache.tomcat.SimpleInstanceManager"/></Arg> </Call> </New> </Arg> @@ -151,7 +157,7 @@ <!-- API Web Application --> <Call name="addHandler"> <Arg> - <New class="org.eclipse.jetty.ee9.webapp.WebAppContext"> + <New class="org.eclipse.jetty.ee11.webapp.WebAppContext"> <Set name="contextPath">/api</Set> <Set name="baseResourceAsString"><Property name="activemq.home" default="."/>/webapps/api</Set> <Set name="logUrlOnStart">true</Set> @@ -159,7 +165,13 @@ runs and TLDs are discovered (otherwise JSP compilation fails with a null TldCache). --> <Call name="setAttribute"> <Arg>org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern</Arg> - <Arg>.*/jetty-ee9-[^/]*\.jar$|.*/jetty-jakarta-servlet-api-[^/]*\.jar$|.*/jakarta\.servlet\.jsp\.jstl.*\.jar$</Arg> + <Arg>.*/jetty-ee11-[^/]*\.jar$|.*/jakarta\.servlet-api-[^/]*\.jar$|.*/jakarta\.servlet\.jsp\.jstl.*\.jar$</Arg> + </Call> + <!-- Jasper needs an InstanceManager in the ServletContext to instantiate JSP/tag classes. + EE11 no longer wires one for a plain exploded WebAppContext, so set a simple one. --> + <Call name="setAttribute"> + <Arg>org.apache.tomcat.InstanceManager</Arg> + <Arg><New class="org.apache.tomcat.SimpleInstanceManager"/></Arg> </Call> </New> </Arg> diff --git a/pom.xml b/pom.xml index 03aaeabea7..9d65caac3d 100644 --- a/pom.xml +++ b/pom.xml @@ -450,16 +450,16 @@ <version>9.10.1</version> </dependency> - <!-- Servlet 5.0 and JSP --> + <!-- Servlet 6.1 and JSP (Jakarta EE 11) --> <dependency> <groupId>jakarta.servlet.jsp</groupId> <artifactId>jakarta.servlet.jsp-api</artifactId> - <version>3.1.1</version> + <version>4.0.0</version> </dependency> <dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> - <version>5.0.0</version> + <version>6.1.0</version> </dependency> <dependency> <groupId>jakarta.websocket</groupId> @@ -831,8 +831,8 @@ </dependency> <dependency> - <groupId>org.eclipse.jetty.ee9</groupId> - <artifactId>jetty-ee9-bom</artifactId> + <groupId>org.eclipse.jetty.ee11</groupId> + <artifactId>jetty-ee11-bom</artifactId> <version>${jetty-version}</version> <type>pom</type> <scope>import</scope> @@ -939,7 +939,7 @@ <dependency> <groupId>jakarta.annotation</groupId> <artifactId>jakarta.annotation-api</artifactId> - <version>2.1.1</version> + <version>3.0.0</version> </dependency> </dependencies> @@ -1024,8 +1024,8 @@ <version>${javacc-maven-plugin-version}</version> </plugin> <plugin> - <groupId>org.eclipse.jetty.ee9</groupId> - <artifactId>jetty-ee9-maven-plugin</artifactId> + <groupId>org.eclipse.jetty.ee11</groupId> + <artifactId>jetty-ee11-maven-plugin</artifactId> <version>${jetty-version}</version> </plugin> <plugin> --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected] For further information, visit: https://activemq.apache.org/contact
