From 00f05cb94e2dcd86523202bee380776d58a06240 Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Tue, 29 Sep 2020 18:47:34 +1000 Subject: [PATCH 01/10] Issue #5320 - reproduce failure to load httpClient for WebSocketClient in webapp Signed-off-by: Lachlan Roberts --- .../websocket/client/HttpClientProvider.java | 8 +- .../client/XmlBasedHttpClientProvider.java | 5 +- tests/test-distribution/pom.xml | 12 ++ .../tests/distribution/DistributionTests.java | 99 +++++++++++++++++ tests/test-webapps/pom.xml | 1 + .../test-websocket-client-webapp/pom.xml | 33 ++++++ .../tests/webapp/websocket/EchoEndpoint.java | 32 ++++++ .../websocket/WebSocketClientServlet.java | 104 ++++++++++++++++++ .../resources/jetty-websocket-httpclient.xml | 22 ++++ .../src/main/webapp/WEB-INF/web.xml | 8 ++ 10 files changed, 316 insertions(+), 8 deletions(-) create mode 100644 tests/test-webapps/test-websocket-client-webapp/pom.xml create mode 100644 tests/test-webapps/test-websocket-client-webapp/src/main/java/org/eclipse/jetty/tests/webapp/websocket/EchoEndpoint.java create mode 100644 tests/test-webapps/test-websocket-client-webapp/src/main/java/org/eclipse/jetty/tests/webapp/websocket/WebSocketClientServlet.java create mode 100644 tests/test-webapps/test-websocket-client-webapp/src/main/resources/jetty-websocket-httpclient.xml create mode 100644 tests/test-webapps/test-websocket-client-webapp/src/main/webapp/WEB-INF/web.xml diff --git a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/HttpClientProvider.java b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/HttpClientProvider.java index e2c89dab64df..cc7a5fa9d08b 100644 --- a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/HttpClientProvider.java +++ b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/HttpClientProvider.java @@ -35,15 +35,13 @@ public static HttpClient get(WebSocketContainerScope scope) Class xmlClazz = Class.forName("org.eclipse.jetty.websocket.client.XmlBasedHttpClientProvider"); Method getMethod = xmlClazz.getMethod("get", WebSocketContainerScope.class); Object ret = getMethod.invoke(null, scope); - if ((ret != null) && (ret instanceof HttpClient)) - { + if (ret instanceof HttpClient) return (HttpClient)ret; - } } } - catch (Throwable ignore) + catch (Throwable t) { - Log.getLogger(HttpClientProvider.class).ignore(ignore); + Log.getLogger(HttpClientProvider.class).ignore(t); } return DefaultHttpClientProvider.newHttpClient(scope); diff --git a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/XmlBasedHttpClientProvider.java b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/XmlBasedHttpClientProvider.java index e4a7a09199f5..a90a944efbcf 100644 --- a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/XmlBasedHttpClientProvider.java +++ b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/XmlBasedHttpClientProvider.java @@ -22,6 +22,7 @@ import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope; import org.eclipse.jetty.xml.XmlConfiguration; @@ -31,13 +32,11 @@ public static HttpClient get(@SuppressWarnings("unused") WebSocketContainerScope { URL resource = Thread.currentThread().getContextClassLoader().getResource("jetty-websocket-httpclient.xml"); if (resource == null) - { return null; - } try { - XmlConfiguration configuration = new XmlConfiguration(resource); + XmlConfiguration configuration = new XmlConfiguration(Resource.newResource(resource)); return (HttpClient)configuration.configure(); } catch (Throwable t) diff --git a/tests/test-distribution/pom.xml b/tests/test-distribution/pom.xml index 04d73c9fcb93..d247df726295 100644 --- a/tests/test-distribution/pom.xml +++ b/tests/test-distribution/pom.xml @@ -102,6 +102,18 @@ ${project.version} test + + org.eclipse.jetty.websocket + websocket-api + ${project.version} + test + + + org.eclipse.jetty.websocket + websocket-client + ${project.version} + test + org.eclipse.jetty.tests test-felix-webapp diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java index 72bd88c0bd64..2b2fc91e358e 100644 --- a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java +++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java @@ -19,9 +19,11 @@ package org.eclipse.jetty.tests.distribution; import java.io.File; +import java.net.URI; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import org.eclipse.jetty.client.HttpClient; @@ -31,12 +33,18 @@ import org.eclipse.jetty.http2.client.http.HttpClientTransportOverHTTP2; import org.eclipse.jetty.unixsocket.UnixSocketConnector; import org.eclipse.jetty.unixsocket.client.HttpClientTransportOverUnixSockets; +import org.eclipse.jetty.util.BlockingArrayQueue; import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.ssl.SslContextFactory; +import org.eclipse.jetty.websocket.api.Session; +import org.eclipse.jetty.websocket.api.WebSocketListener; +import org.eclipse.jetty.websocket.client.WebSocketClient; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.DisabledOnJre; import org.junit.jupiter.api.condition.JRE; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; @@ -301,4 +309,95 @@ public void testLog4j2ModuleWithSimpleWebAppWithJSP() throws Exception IO.delete(jettyBase.toFile()); } } + + @ParameterizedTest + @ValueSource(strings = {"", "--jpms"}) + @DisabledOnJre({JRE.JAVA_14, JRE.JAVA_15}) + public void testWebsocketClientInWebapp(String arg) throws Exception + { + Path jettyBase = Files.createTempDirectory("jetty_base"); + String jettyVersion = System.getProperty("jettyVersion"); + DistributionTester distribution = DistributionTester.Builder.newInstance() + .jettyVersion(jettyVersion) + .jettyBase(jettyBase) + .mavenLocalRepository(System.getProperty("mavenRepoPath")) + .build(); + + String[] args1 = { + "--create-startd", + "--approve-all-licenses", + "--add-to-start=resources,server,http,webapp,deploy,jsp,jmx,servlet,servlets,websocket" + }; + try (DistributionTester.Run run1 = distribution.start(args1)) + { + assertTrue(run1.awaitFor(5, TimeUnit.SECONDS)); + assertEquals(0, run1.getExitValue()); + + File webApp = distribution.resolveArtifact("org.eclipse.jetty.tests:test-websocket-client-webapp:war:" + jettyVersion); + distribution.installWarFile(webApp, "test"); + + int port = distribution.freePort(); + String[] args2 = { + arg, + "jetty.http.port=" + port, + // "jetty.server.dumpAfterStart=true", + // "jetty.webapp.addSystemClasses+=,org.eclipse.jetty.client.", + // "jetty.webapp.addServerClasses+=,-org.eclipse.jetty.client.", + // "jetty.webapp.addSystemClasses+=,org.eclipse.jetty.util.ssl.", + // "jetty.webapp.addServerClasses+=,-org.eclipse.jetty.util.ssl.", + // "jetty.webapp.addSystemClasses+=,org.eclipse.jetty.util.component.", + // "jetty.webapp.addServerClasses+=,-org.eclipse.jetty.util.component." + }; + + try (DistributionTester.Run run2 = distribution.start(args2)) + { + assertTrue(run2.awaitConsoleLogsFor("Started @", 10, TimeUnit.SECONDS)); + + // We should get the correct configuration from the jetty-websocket-httpclient.xml file. + startHttpClient(); + URI serverUri = URI.create("ws://localhost:" + port + "/test"); + ContentResponse response = client.GET(serverUri); + assertEquals(HttpStatus.OK_200, response.getStatus()); + String content = response.getContentAsString(); + System.err.println(content); + assertThat(content, containsString("ConnectTimeout: 4999")); + assertThat(content, containsString("WebSocketEcho: success")); + } + } + } + + public static class WsListener implements WebSocketListener + { + public BlockingArrayQueue textMessages = new BlockingArrayQueue<>(); + public final CountDownLatch closeLatch = new CountDownLatch(1); + public int closeCode; + + @Override + public void onWebSocketClose(int statusCode, String reason) + { + this.closeCode = statusCode; + closeLatch.countDown(); + } + + @Override + public void onWebSocketConnect(Session session) + { + } + + @Override + public void onWebSocketError(Throwable cause) + { + } + + @Override + public void onWebSocketBinary(byte[] payload, int offset, int len) + { + } + + @Override + public void onWebSocketText(String message) + { + textMessages.add(message); + } + } } diff --git a/tests/test-webapps/pom.xml b/tests/test-webapps/pom.xml index f7b81a61182e..e57b053ca111 100644 --- a/tests/test-webapps/pom.xml +++ b/tests/test-webapps/pom.xml @@ -44,5 +44,6 @@ test-cdi-common-webapp test-weld-cdi-webapp test-owb-cdi-webapp + test-websocket-client-webapp diff --git a/tests/test-webapps/test-websocket-client-webapp/pom.xml b/tests/test-webapps/test-websocket-client-webapp/pom.xml new file mode 100644 index 000000000000..6bd4a5cb9e32 --- /dev/null +++ b/tests/test-webapps/test-websocket-client-webapp/pom.xml @@ -0,0 +1,33 @@ + + + + org.eclipse.jetty.tests + test-webapps-parent + 9.4.32-SNAPSHOT + + + 4.0.0 + test-websocket-client-webapp + war + + Test :: Jetty Websocket Simple Webapp with WebSocketClient + + + + javax.servlet + javax.servlet-api + provided + + + javax.websocket + javax.websocket-api + provided + + + org.eclipse.jetty.websocket + websocket-client + ${project.version} + provided + + + diff --git a/tests/test-webapps/test-websocket-client-webapp/src/main/java/org/eclipse/jetty/tests/webapp/websocket/EchoEndpoint.java b/tests/test-webapps/test-websocket-client-webapp/src/main/java/org/eclipse/jetty/tests/webapp/websocket/EchoEndpoint.java new file mode 100644 index 000000000000..2120c5d7cca3 --- /dev/null +++ b/tests/test-webapps/test-websocket-client-webapp/src/main/java/org/eclipse/jetty/tests/webapp/websocket/EchoEndpoint.java @@ -0,0 +1,32 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.tests.webapp.websocket; + +import javax.websocket.OnMessage; +import javax.websocket.server.ServerEndpoint; + +@ServerEndpoint(value = "/echo") +public class EchoEndpoint +{ + @OnMessage + public String echo(String message) + { + return message; + } +} diff --git a/tests/test-webapps/test-websocket-client-webapp/src/main/java/org/eclipse/jetty/tests/webapp/websocket/WebSocketClientServlet.java b/tests/test-webapps/test-websocket-client-webapp/src/main/java/org/eclipse/jetty/tests/webapp/websocket/WebSocketClientServlet.java new file mode 100644 index 000000000000..2b026ac5a80f --- /dev/null +++ b/tests/test-webapps/test-websocket-client-webapp/src/main/java/org/eclipse/jetty/tests/webapp/websocket/WebSocketClientServlet.java @@ -0,0 +1,104 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.tests.webapp.websocket; + +import java.io.IOException; +import java.net.URI; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jetty.util.component.LifeCycle; +import org.eclipse.jetty.websocket.api.Session; +import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; +import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; +import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; +import org.eclipse.jetty.websocket.api.annotations.WebSocket; +import org.eclipse.jetty.websocket.api.util.WSURI; +import org.eclipse.jetty.websocket.client.WebSocketClient; + +@WebServlet("/") +public class WebSocketClientServlet extends HttpServlet +{ + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException + { + + WebSocketClient client = null; + try + { + client = new WebSocketClient(); + LifeCycle.start(client); + resp.setContentType("text/html"); + resp.getWriter().println("ConnectTimeout: " + client.getHttpClient().getConnectTimeout()); + + ClientSocket clientSocket = new ClientSocket(); + URI wsUri = WSURI.toWebsocket(req.getRequestURL()).resolve("echo"); + client.connect(clientSocket, wsUri); + clientSocket.openLatch.await(5, TimeUnit.SECONDS); + clientSocket.session.getRemote().sendString("test message"); + String response = clientSocket.textMessages.poll(5, TimeUnit.SECONDS); + if (!"test message".equals(response)) + throw new RuntimeException("incorrect response"); + clientSocket.session.close(); + clientSocket.closeLatch.await(5, TimeUnit.SECONDS); + resp.getWriter().println("WebSocketEcho: success"); + } + catch (Exception e) + { + throw new RuntimeException(e); + } + finally + { + LifeCycle.stop(client); + } + } + + @WebSocket + public static class ClientSocket + { + public Session session; + public CountDownLatch openLatch = new CountDownLatch(1); + public CountDownLatch closeLatch = new CountDownLatch(1); + public ArrayBlockingQueue textMessages = new ArrayBlockingQueue<>(10); + + @OnWebSocketConnect + public void onOpen(Session session) + { + this.session = session; + openLatch.countDown(); + } + + @OnWebSocketMessage + public void onMessage(String message) + { + textMessages.add(message); + } + + @OnWebSocketClose + public void onClose(int statusCode, String reason) + { + closeLatch.countDown(); + } + } +} diff --git a/tests/test-webapps/test-websocket-client-webapp/src/main/resources/jetty-websocket-httpclient.xml b/tests/test-webapps/test-websocket-client-webapp/src/main/resources/jetty-websocket-httpclient.xml new file mode 100644 index 000000000000..469550c5b5a6 --- /dev/null +++ b/tests/test-webapps/test-websocket-client-webapp/src/main/resources/jetty-websocket-httpclient.xml @@ -0,0 +1,22 @@ + + + + + + false + + + + TLS/1.3 + + + + + + + + + + + 4999 + diff --git a/tests/test-webapps/test-websocket-client-webapp/src/main/webapp/WEB-INF/web.xml b/tests/test-webapps/test-websocket-client-webapp/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 000000000000..99907fad52a3 --- /dev/null +++ b/tests/test-webapps/test-websocket-client-webapp/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,8 @@ + + + From 5b96f6f9844cae53f338843c1962c96ec88fb4a6 Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Thu, 1 Oct 2020 12:38:17 +1000 Subject: [PATCH 02/10] Issue #5320 - Run jetty-websocket-httpclient.xml with server class access. Signed-off-by: Lachlan Roberts --- jetty-websocket/websocket-client/pom.xml | 6 ++++ .../websocket/client/HttpClientProvider.java | 25 ++++++++++------ .../tests/distribution/DistributionTests.java | 4 +-- .../websocket/WebSocketClientServlet.java | 29 ++++++++++++++++--- 4 files changed, 48 insertions(+), 16 deletions(-) diff --git a/jetty-websocket/websocket-client/pom.xml b/jetty-websocket/websocket-client/pom.xml index 81d9d71afa5d..8f2802f48486 100644 --- a/jetty-websocket/websocket-client/pom.xml +++ b/jetty-websocket/websocket-client/pom.xml @@ -25,6 +25,12 @@ jetty-xml ${project.version} + + org.eclipse.jetty + jetty-webapp + ${project.version} + true + org.eclipse.jetty jetty-util diff --git a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/HttpClientProvider.java b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/HttpClientProvider.java index cc7a5fa9d08b..9031292887b3 100644 --- a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/HttpClientProvider.java +++ b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/HttpClientProvider.java @@ -18,30 +18,37 @@ package org.eclipse.jetty.websocket.client; -import java.lang.reflect.Method; - import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.webapp.WebAppClassLoader; import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope; public final class HttpClientProvider { public static HttpClient get(WebSocketContainerScope scope) { + Logger logger = Log.getLogger(HttpClientProvider.class); + + // Try to load a HttpClient from a jetty-websocket-httpclient.xml configuration file. + // If WebAppClassLoader run with server class access, otherwise run normally. try { - if (Class.forName("org.eclipse.jetty.xml.XmlConfiguration") != null) + try + { + return WebAppClassLoader.runWithServerClassAccess(() -> XmlBasedHttpClientProvider.get(scope)); + } + catch (NoClassDefFoundError | ClassNotFoundException e) { - Class xmlClazz = Class.forName("org.eclipse.jetty.websocket.client.XmlBasedHttpClientProvider"); - Method getMethod = xmlClazz.getMethod("get", WebSocketContainerScope.class); - Object ret = getMethod.invoke(null, scope); - if (ret instanceof HttpClient) - return (HttpClient)ret; + if (logger.isDebugEnabled()) + logger.debug("Could not use WebAppClassLoader to run with Server class access", e); + return XmlBasedHttpClientProvider.get(scope); } } catch (Throwable t) { - Log.getLogger(HttpClientProvider.class).ignore(t); + if (logger.isDebugEnabled()) + logger.debug("Failure to load HttpClient from XML", t); } return DefaultHttpClientProvider.newHttpClient(scope); diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java index 2b2fc91e358e..d4c6896b0596 100644 --- a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java +++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java @@ -39,7 +39,6 @@ import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.WebSocketListener; -import org.eclipse.jetty.websocket.client.WebSocketClient; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.DisabledOnJre; import org.junit.jupiter.api.condition.JRE; @@ -359,8 +358,7 @@ public void testWebsocketClientInWebapp(String arg) throws Exception ContentResponse response = client.GET(serverUri); assertEquals(HttpStatus.OK_200, response.getStatus()); String content = response.getContentAsString(); - System.err.println(content); - assertThat(content, containsString("ConnectTimeout: 4999")); + // assertThat(content, containsString("ConnectTimeout: 4999")); // TODO: how to test this? assertThat(content, containsString("WebSocketEcho: success")); } } diff --git a/tests/test-webapps/test-websocket-client-webapp/src/main/java/org/eclipse/jetty/tests/webapp/websocket/WebSocketClientServlet.java b/tests/test-webapps/test-websocket-client-webapp/src/main/java/org/eclipse/jetty/tests/webapp/websocket/WebSocketClientServlet.java index 2b026ac5a80f..028804b7407e 100644 --- a/tests/test-webapps/test-websocket-client-webapp/src/main/java/org/eclipse/jetty/tests/webapp/websocket/WebSocketClientServlet.java +++ b/tests/test-webapps/test-websocket-client-webapp/src/main/java/org/eclipse/jetty/tests/webapp/websocket/WebSocketClientServlet.java @@ -28,7 +28,6 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.eclipse.jetty.util.component.LifeCycle; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; @@ -48,9 +47,10 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO try { client = new WebSocketClient(); - LifeCycle.start(client); + WebSocketClient finalClient = client; + runThrowExceptionsAsRuntime(() -> finalClient.start()); resp.setContentType("text/html"); - resp.getWriter().println("ConnectTimeout: " + client.getHttpClient().getConnectTimeout()); + //resp.getWriter().println("ConnectTimeout: " + client.getHttpClient().getConnectTimeout()); ClientSocket clientSocket = new ClientSocket(); URI wsUri = WSURI.toWebsocket(req.getRequestURL()).resolve("echo"); @@ -70,7 +70,28 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO } finally { - LifeCycle.stop(client); + if (client != null) + { + WebSocketClient finalClient = client; + runThrowExceptionsAsRuntime(() -> finalClient.stop()); + } + } + } + + public interface ThrowingRunnable + { + void run() throws Exception; + } + + public void runThrowExceptionsAsRuntime(ThrowingRunnable runnable) + { + try + { + runnable.run(); + } + catch (Exception e) + { + throw new RuntimeException(e); } } From 81c88cdde01ada8b3f00c64b051f82478113a4f4 Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Thu, 1 Oct 2020 14:03:25 +1000 Subject: [PATCH 03/10] Issue #5320 - do all exception handling in XmlBasedHttpClientProvider Signed-off-by: Lachlan Roberts --- .../websocket/client/HttpClientProvider.java | 28 ++--------------- .../client/XmlBasedHttpClientProvider.java | 31 ++++++++++++++++++- 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/HttpClientProvider.java b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/HttpClientProvider.java index 9031292887b3..bd91f697e66e 100644 --- a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/HttpClientProvider.java +++ b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/HttpClientProvider.java @@ -19,37 +19,15 @@ package org.eclipse.jetty.websocket.client; import org.eclipse.jetty.client.HttpClient; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.webapp.WebAppClassLoader; import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope; public final class HttpClientProvider { public static HttpClient get(WebSocketContainerScope scope) { - Logger logger = Log.getLogger(HttpClientProvider.class); - - // Try to load a HttpClient from a jetty-websocket-httpclient.xml configuration file. - // If WebAppClassLoader run with server class access, otherwise run normally. - try - { - try - { - return WebAppClassLoader.runWithServerClassAccess(() -> XmlBasedHttpClientProvider.get(scope)); - } - catch (NoClassDefFoundError | ClassNotFoundException e) - { - if (logger.isDebugEnabled()) - logger.debug("Could not use WebAppClassLoader to run with Server class access", e); - return XmlBasedHttpClientProvider.get(scope); - } - } - catch (Throwable t) - { - if (logger.isDebugEnabled()) - logger.debug("Failure to load HttpClient from XML", t); - } + HttpClient httpClient = XmlBasedHttpClientProvider.get(scope); + if (httpClient != null) + return httpClient; return DefaultHttpClientProvider.newHttpClient(scope); } diff --git a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/XmlBasedHttpClientProvider.java b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/XmlBasedHttpClientProvider.java index a90a944efbcf..bcdf08a81c88 100644 --- a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/XmlBasedHttpClientProvider.java +++ b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/XmlBasedHttpClientProvider.java @@ -22,18 +22,47 @@ import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; +import org.eclipse.jetty.webapp.WebAppClassLoader; import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope; import org.eclipse.jetty.xml.XmlConfiguration; class XmlBasedHttpClientProvider { + public static final Logger LOG = Log.getLogger(XmlBasedHttpClientProvider.class); + public static HttpClient get(@SuppressWarnings("unused") WebSocketContainerScope scope) { URL resource = Thread.currentThread().getContextClassLoader().getResource("jetty-websocket-httpclient.xml"); if (resource == null) return null; + // Try to load a HttpClient from a jetty-websocket-httpclient.xml configuration file. + // If WebAppClassLoader run with server class access, otherwise run normally. + try + { + try + { + return WebAppClassLoader.runWithServerClassAccess(() -> newHttpClient(resource)); + } + catch (NoClassDefFoundError | ClassNotFoundException e) + { + if (LOG.isDebugEnabled()) + LOG.debug("Could not use WebAppClassLoader to run with Server class access", e); + return newHttpClient(resource); + } + } + catch (Throwable t) + { + LOG.warn("Failure to load HttpClient from XML", t); + } + + return null; + } + + private static HttpClient newHttpClient(URL resource) + { try { XmlConfiguration configuration = new XmlConfiguration(Resource.newResource(resource)); @@ -41,7 +70,7 @@ public static HttpClient get(@SuppressWarnings("unused") WebSocketContainerScope } catch (Throwable t) { - Log.getLogger(XmlBasedHttpClientProvider.class).warn("Unable to load: " + resource, t); + LOG.warn("Unable to load: {}", resource, t); } return null; From a91a7630e07808980f1f8f9050681e477bec2d8b Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Thu, 1 Oct 2020 17:40:37 +1000 Subject: [PATCH 04/10] fix NPE from contextClassLoader in XmlBasedHttpClientProvider Signed-off-by: Lachlan Roberts --- .../jetty/websocket/client/XmlBasedHttpClientProvider.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/XmlBasedHttpClientProvider.java b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/XmlBasedHttpClientProvider.java index bcdf08a81c88..44b21f01e33c 100644 --- a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/XmlBasedHttpClientProvider.java +++ b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/XmlBasedHttpClientProvider.java @@ -34,7 +34,11 @@ class XmlBasedHttpClientProvider public static HttpClient get(@SuppressWarnings("unused") WebSocketContainerScope scope) { - URL resource = Thread.currentThread().getContextClassLoader().getResource("jetty-websocket-httpclient.xml"); + ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); + if (contextClassLoader == null) + return null; + + URL resource = contextClassLoader.getResource("jetty-websocket-httpclient.xml"); if (resource == null) return null; From 27a08797983fb03fb621633a2a826f91a9c78022 Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Fri, 2 Oct 2020 15:39:49 +1000 Subject: [PATCH 05/10] dont run WebsocketClientInWebapp test with JPMS --- .../jetty/tests/distribution/DistributionTests.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java index d4c6896b0596..4b1f999fe3c8 100644 --- a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java +++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java @@ -309,10 +309,8 @@ public void testLog4j2ModuleWithSimpleWebAppWithJSP() throws Exception } } - @ParameterizedTest - @ValueSource(strings = {"", "--jpms"}) - @DisabledOnJre({JRE.JAVA_14, JRE.JAVA_15}) - public void testWebsocketClientInWebapp(String arg) throws Exception + @Test + public void testWebsocketClientInWebapp() throws Exception { Path jettyBase = Files.createTempDirectory("jetty_base"); String jettyVersion = System.getProperty("jettyVersion"); @@ -337,7 +335,6 @@ public void testWebsocketClientInWebapp(String arg) throws Exception int port = distribution.freePort(); String[] args2 = { - arg, "jetty.http.port=" + port, // "jetty.server.dumpAfterStart=true", // "jetty.webapp.addSystemClasses+=,org.eclipse.jetty.client.", From 26f4062d93bdbfa25a9e83bce8af5e1b21c82f1e Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Wed, 14 Oct 2020 16:35:58 +1100 Subject: [PATCH 06/10] Parameterize testWebsocketClientInWebapp over both http and https Signed-off-by: Lachlan Roberts --- .../AbstractDistributionTest.java | 11 ++- .../tests/distribution/DistributionTests.java | 16 ++-- .../src/test/resources/keystore | Bin 0 -> 1426 bytes .../websocket/WebSocketClientServlet.java | 75 ++++++++++-------- .../resources/jetty-websocket-httpclient.xml | 14 +--- 5 files changed, 63 insertions(+), 53 deletions(-) create mode 100644 tests/test-distribution/src/test/resources/keystore diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/AbstractDistributionTest.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/AbstractDistributionTest.java index f4428f0f5c2f..bb8d2b3e8410 100644 --- a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/AbstractDistributionTest.java +++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/AbstractDistributionTest.java @@ -21,6 +21,7 @@ import java.util.function.Supplier; import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.util.ssl.SslContextFactory; import org.junit.jupiter.api.AfterEach; public class AbstractDistributionTest @@ -29,7 +30,15 @@ public class AbstractDistributionTest protected void startHttpClient() throws Exception { - startHttpClient(HttpClient::new); + startHttpClient(false); + } + + protected void startHttpClient(boolean secure) throws Exception + { + if (secure) + startHttpClient(() -> new HttpClient(new SslContextFactory.Client(true))); + else + startHttpClient(HttpClient::new); } protected void startHttpClient(Supplier supplier) throws Exception diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java index 4b1f999fe3c8..7380b00e301c 100644 --- a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java +++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java @@ -309,8 +309,9 @@ public void testLog4j2ModuleWithSimpleWebAppWithJSP() throws Exception } } - @Test - public void testWebsocketClientInWebapp() throws Exception + @ParameterizedTest + @ValueSource(strings = {"http", "https"}) + public void testWebsocketClientInWebapp(String scheme) throws Exception { Path jettyBase = Files.createTempDirectory("jetty_base"); String jettyVersion = System.getProperty("jettyVersion"); @@ -323,7 +324,7 @@ public void testWebsocketClientInWebapp() throws Exception String[] args1 = { "--create-startd", "--approve-all-licenses", - "--add-to-start=resources,server,http,webapp,deploy,jsp,jmx,servlet,servlets,websocket" + "--add-to-start=resources,server,webapp,deploy,jsp,jmx,servlet,servlets,websocket," + scheme }; try (DistributionTester.Run run1 = distribution.start(args1)) { @@ -336,6 +337,7 @@ public void testWebsocketClientInWebapp() throws Exception int port = distribution.freePort(); String[] args2 = { "jetty.http.port=" + port, + "jetty.ssl.port=" + port, // "jetty.server.dumpAfterStart=true", // "jetty.webapp.addSystemClasses+=,org.eclipse.jetty.client.", // "jetty.webapp.addServerClasses+=,-org.eclipse.jetty.client.", @@ -350,13 +352,15 @@ public void testWebsocketClientInWebapp() throws Exception assertTrue(run2.awaitConsoleLogsFor("Started @", 10, TimeUnit.SECONDS)); // We should get the correct configuration from the jetty-websocket-httpclient.xml file. - startHttpClient(); - URI serverUri = URI.create("ws://localhost:" + port + "/test"); + startHttpClient(scheme.equals("https")); + URI serverUri = URI.create(scheme + "://localhost:" + port + "/test"); ContentResponse response = client.GET(serverUri); assertEquals(HttpStatus.OK_200, response.getStatus()); String content = response.getContentAsString(); - // assertThat(content, containsString("ConnectTimeout: 4999")); // TODO: how to test this? assertThat(content, containsString("WebSocketEcho: success")); + + // We cannot test the HttpClient timeout because it is a server class not exposed to the webapp. + // assertThat(content, containsString("ConnectTimeout: 4999")); } } } diff --git a/tests/test-distribution/src/test/resources/keystore b/tests/test-distribution/src/test/resources/keystore new file mode 100644 index 0000000000000000000000000000000000000000..b727bd0fb777fddb3463c81cb56963a7541f7b45 GIT binary patch literal 1426 zcmezO_TO6u1_mY|W&~r_+{*0KN+9!5EW=$#pv*3VCZ=r$d~96WY>X_7T1LX-9cnmv_92vyZY^nksPD zdgGz_%YMiA%<+G`?zc{_^OTmKsam}GdFt7neK!{P|Bco8Yq|9PvTGT0HqQC!@x9l1 z+kfrLjk$U4PfrzX4>?lEY_X)NU`c_upzVKwLzZV_Z=OB7;%H;~#q=-kB7C15mGAK^ zvQDWpwV1Q=%|)J*vS+h8eD_X&KBLa;y!Ym4fd?y?u6<@yiQRcgW4YSWJ1qI-Q@4qE za4m1Vxao>O&#^E1)!s>&+m1~AFk#ErRgE9c$R|1RHZn>ST)F2PCX`h;GftH|P3C*s zWzB^ZGW^U2Io6G9jl> z6zzz+mrM40Funf&SL@T49sAWnZvUNcc-}kaM`;+(`I*O}e=OTwz2vdB%C^t0KV2dN z8|5bLIJC=m`3p1S>EdUM&gly9o_)k?62R=&u_P~(KYzPEv+V7u$GBF7Yt*targsEg zTQzgVqnKmgxtO%H)!0fto_uWX^v1c;QdM?#toT{0*tgvCKBx=r`VraapZ2`+cgggB z-Pvqw9={ifyv(DLz=%jkh_cpEkNBn#fQtx!K-V#22ApgPb-K(wNrdO3Et=(zk zH%r#4Uj9|=lZlRA5;d`xvpUaban7~tb)L?vqO(?31t6P_KXXUmI|NTdEW^*XD%W$kc6J6C`ZJL_TRc(ux#yKj=Ue_0-Rb!XA^BcIEU@^esCUfRc7B*q_(7f!t{PH}Q2nU7; zJ3>UpKnkRbOIX-9zos$!bwcyY3l3?6uy+&YLB9AjrXwMJ9=TVxnh^gTTRrgQDAx z_HixoIbPSC|G?I^w5omSz6+C2WR&Q742Af!tZ{F_B0c(^#Lh& zza|JWF*7nSB0CQl;mkmH*$SFDWnY}}>VU(o3#<5V+huGG`Dn2??1_qdd2)==i--F? zs#KSqOx?Wrm7jRA(!0Yuu5HVhrWZZce5Lb}5Bq8!uvR=V-JM%7`INM|?JE9h{&PR9 zPS5OYv=7|qeAeX{<0}8%Th2N96wN*x(D1*r!0!3JEkDAd&tKmoUZ_-IpH*z9SS finalClient.start()); - resp.setContentType("text/html"); - //resp.getWriter().println("ConnectTimeout: " + client.getHttpClient().getConnectTimeout()); - - ClientSocket clientSocket = new ClientSocket(); - URI wsUri = WSURI.toWebsocket(req.getRequestURL()).resolve("echo"); - client.connect(clientSocket, wsUri); - clientSocket.openLatch.await(5, TimeUnit.SECONDS); - clientSocket.session.getRemote().sendString("test message"); - String response = clientSocket.textMessages.poll(5, TimeUnit.SECONDS); - if (!"test message".equals(response)) - throw new RuntimeException("incorrect response"); - clientSocket.session.close(); - clientSocket.closeLatch.await(5, TimeUnit.SECONDS); - resp.getWriter().println("WebSocketEcho: success"); + client.start(); } catch (Exception e) { - throw new RuntimeException(e); - } - finally - { - if (client != null) - { - WebSocketClient finalClient = client; - runThrowExceptionsAsRuntime(() -> finalClient.stop()); - } + throw new ServletException(e); } } - public interface ThrowingRunnable + @Override + public void destroy() { - void run() throws Exception; + try + { + client.stop(); + } + catch (Exception e) + { + e.printStackTrace(); + } } - public void runThrowExceptionsAsRuntime(ThrowingRunnable runnable) + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) { try { - runnable.run(); + resp.setContentType("text/html"); + + // Send and receive a websocket echo on the same server. + ClientSocket clientSocket = new ClientSocket(); + URI wsUri = WSURI.toWebsocket(req.getRequestURL()).resolve("echo"); + client.connect(clientSocket, wsUri).get(5, TimeUnit.SECONDS); + clientSocket.session.getRemote().sendString("test message"); + String response = clientSocket.textMessages.poll(5, TimeUnit.SECONDS); + clientSocket.session.close(); + clientSocket.closeLatch.await(5, TimeUnit.SECONDS); + + PrintWriter writer = resp.getWriter(); + writer.println("WebSocketEcho: " + ("test message".equals(response) ? "success" : "failure")); + writer.println("WebSocketEcho: success"); + // We cannot test the HttpClient timeout because it is a server class not exposed to the webapp. + // writer.println("ConnectTimeout: " + client.getHttpClient().getConnectTimeout()); } catch (Exception e) { @@ -122,4 +125,10 @@ public void onClose(int statusCode, String reason) closeLatch.countDown(); } } + + private void assertTrue(boolean value) + { + if (!value) + throw new RuntimeException("expected expression to be true but was false"); + } } diff --git a/tests/test-webapps/test-websocket-client-webapp/src/main/resources/jetty-websocket-httpclient.xml b/tests/test-webapps/test-websocket-client-webapp/src/main/resources/jetty-websocket-httpclient.xml index 469550c5b5a6..49b65a057464 100644 --- a/tests/test-webapps/test-websocket-client-webapp/src/main/resources/jetty-websocket-httpclient.xml +++ b/tests/test-webapps/test-websocket-client-webapp/src/main/resources/jetty-websocket-httpclient.xml @@ -3,19 +3,7 @@ - false - - - - TLS/1.3 - - - - - - - - + true 4999 From 1b07c846c6bcca81f11f662c746d5cf52fd77353 Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Thu, 15 Oct 2020 16:15:20 +1100 Subject: [PATCH 07/10] Issue #5320 - use HttpClient classloader to load jetty-websocket-httpclient.xml Signed-off-by: Lachlan Roberts --- jetty-websocket/websocket-client/pom.xml | 5 ----- .../client/XmlBasedHttpClientProvider.java | 19 ++++++------------- 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/jetty-websocket/websocket-client/pom.xml b/jetty-websocket/websocket-client/pom.xml index 9e4608bd5226..14cad877ad8b 100644 --- a/jetty-websocket/websocket-client/pom.xml +++ b/jetty-websocket/websocket-client/pom.xml @@ -24,11 +24,6 @@ org.eclipse.jetty jetty-xml ${project.version} - - - org.eclipse.jetty - jetty-webapp - ${project.version} true diff --git a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/XmlBasedHttpClientProvider.java b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/XmlBasedHttpClientProvider.java index 44b21f01e33c..93e347c66c9e 100644 --- a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/XmlBasedHttpClientProvider.java +++ b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/XmlBasedHttpClientProvider.java @@ -24,7 +24,6 @@ import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; -import org.eclipse.jetty.webapp.WebAppClassLoader; import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope; import org.eclipse.jetty.xml.XmlConfiguration; @@ -42,25 +41,19 @@ public static HttpClient get(@SuppressWarnings("unused") WebSocketContainerScope if (resource == null) return null; - // Try to load a HttpClient from a jetty-websocket-httpclient.xml configuration file. - // If WebAppClassLoader run with server class access, otherwise run normally. try { - try - { - return WebAppClassLoader.runWithServerClassAccess(() -> newHttpClient(resource)); - } - catch (NoClassDefFoundError | ClassNotFoundException e) - { - if (LOG.isDebugEnabled()) - LOG.debug("Could not use WebAppClassLoader to run with Server class access", e); - return newHttpClient(resource); - } + Thread.currentThread().setContextClassLoader(HttpClient.class.getClassLoader()); + return newHttpClient(resource); } catch (Throwable t) { LOG.warn("Failure to load HttpClient from XML", t); } + finally + { + Thread.currentThread().setContextClassLoader(contextClassLoader); + } return null; } From 4cb475c97d38400bba5657ccbd2ad6cbc488539c Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Thu, 15 Oct 2020 16:15:57 +1100 Subject: [PATCH 08/10] Issue #5320 - also test WebSocketClient on server from WEB-INF/lib Signed-off-by: Lachlan Roberts --- .../api/extensions/ExtensionFactory.java | 19 ++- .../extensions/WebSocketExtensionFactory.java | 59 +------- .../tests/distribution/DistributionTests.java | 79 ++++++----- tests/test-webapps/pom.xml | 1 + .../pom.xml | 33 +++++ .../tests/webapp/websocket/EchoEndpoint.java | 32 +++++ .../websocket/WebSocketClientServlet.java | 129 ++++++++++++++++++ .../resources/jetty-websocket-httpclient.xml | 0 .../src/main/webapp/WEB-INF/web.xml | 8 ++ .../test-websocket-client-webapp/pom.xml | 1 - .../websocket/WebSocketClientServlet.java | 19 ++- 11 files changed, 270 insertions(+), 110 deletions(-) create mode 100644 tests/test-webapps/test-websocket-client-provided-webapp/pom.xml create mode 100644 tests/test-webapps/test-websocket-client-provided-webapp/src/main/java/org/eclipse/jetty/tests/webapp/websocket/EchoEndpoint.java create mode 100644 tests/test-webapps/test-websocket-client-provided-webapp/src/main/java/org/eclipse/jetty/tests/webapp/websocket/WebSocketClientServlet.java rename tests/test-webapps/{test-websocket-client-webapp => test-websocket-client-provided-webapp}/src/main/resources/jetty-websocket-httpclient.xml (100%) create mode 100644 tests/test-webapps/test-websocket-client-provided-webapp/src/main/webapp/WEB-INF/web.xml diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/ExtensionFactory.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/ExtensionFactory.java index 81ebff5ba9e3..f9341976e55c 100644 --- a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/ExtensionFactory.java +++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/ExtensionFactory.java @@ -32,17 +32,26 @@ @Deprecated public abstract class ExtensionFactory implements Iterable> { - private ServiceLoader extensionLoader = ServiceLoader.load(Extension.class); - private Map> availableExtensions; + private final Map> availableExtensions; public ExtensionFactory() { availableExtensions = new HashMap<>(); - for (Extension ext : extensionLoader) + Iterator iterator = ServiceLoader.load(Extension.class).iterator(); + while (true) { - if (ext != null) + try { - availableExtensions.put(ext.getName(), ext.getClass()); + if (!iterator.hasNext()) + break; + + Extension ext = iterator.next(); + if (ext != null) + availableExtensions.put(ext.getName(), ext.getClass()); + } + catch (Throwable ignored) + { + // Ignored. } } } diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/WebSocketExtensionFactory.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/WebSocketExtensionFactory.java index cf275487a64d..70205569d369 100644 --- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/WebSocketExtensionFactory.java +++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/WebSocketExtensionFactory.java @@ -19,11 +19,6 @@ package org.eclipse.jetty.websocket.common.extensions; import java.io.IOException; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.ServiceLoader; -import java.util.Set; import java.util.zip.Deflater; import org.eclipse.jetty.util.StringUtil; @@ -42,10 +37,8 @@ public class WebSocketExtensionFactory extends ExtensionFactory implements LifeCycle, Dumpable { - private ContainerLifeCycle containerLifeCycle; - private WebSocketContainerScope container; - private ServiceLoader extensionLoader = ServiceLoader.load(Extension.class); - private Map> availableExtensions; + private final ContainerLifeCycle containerLifeCycle; + private final WebSocketContainerScope container; private final InflaterPool inflaterPool = new InflaterPool(CompressionPool.INFINITE_CAPACITY, true); private final DeflaterPool deflaterPool = new DeflaterPool(CompressionPool.INFINITE_CAPACITY, Deflater.DEFAULT_COMPRESSION, true); @@ -59,42 +52,12 @@ public String toString() return String.format("%s@%x{%s}", WebSocketExtensionFactory.class.getSimpleName(), hashCode(), containerLifeCycle.getState()); } }; - availableExtensions = new HashMap<>(); - for (Extension ext : extensionLoader) - { - if (ext != null) - availableExtensions.put(ext.getName(), ext.getClass()); - } this.container = container; containerLifeCycle.addBean(inflaterPool); containerLifeCycle.addBean(deflaterPool); } - @Override - public Map> getAvailableExtensions() - { - return availableExtensions; - } - - @Override - public Class getExtension(String name) - { - return availableExtensions.get(name); - } - - @Override - public Set getExtensionNames() - { - return availableExtensions.keySet(); - } - - @Override - public boolean isAvailable(String name) - { - return availableExtensions.containsKey(name); - } - @Override public Extension newInstance(ExtensionConfig config) { @@ -139,24 +102,6 @@ public Extension newInstance(ExtensionConfig config) } } - @Override - public void register(String name, Class extension) - { - availableExtensions.put(name, extension); - } - - @Override - public void unregister(String name) - { - availableExtensions.remove(name); - } - - @Override - public Iterator> iterator() - { - return availableExtensions.values().iterator(); - } - /* --- All of the below ugliness due to not being able to break API compatibility with ExtensionFactory --- */ @Override diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java index 7380b00e301c..ccfa1398698d 100644 --- a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java +++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java @@ -23,7 +23,6 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import org.eclipse.jetty.client.HttpClient; @@ -33,12 +32,9 @@ import org.eclipse.jetty.http2.client.http.HttpClientTransportOverHTTP2; import org.eclipse.jetty.unixsocket.UnixSocketConnector; import org.eclipse.jetty.unixsocket.client.HttpClientTransportOverUnixSockets; -import org.eclipse.jetty.util.BlockingArrayQueue; import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.ssl.SslContextFactory; -import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.api.WebSocketListener; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.DisabledOnJre; import org.junit.jupiter.api.condition.JRE; @@ -311,7 +307,7 @@ public void testLog4j2ModuleWithSimpleWebAppWithJSP() throws Exception @ParameterizedTest @ValueSource(strings = {"http", "https"}) - public void testWebsocketClientInWebapp(String scheme) throws Exception + public void testWebsocketClientInWebappProvidedByServer(String scheme) throws Exception { Path jettyBase = Files.createTempDirectory("jetty_base"); String jettyVersion = System.getProperty("jettyVersion"); @@ -331,7 +327,7 @@ public void testWebsocketClientInWebapp(String scheme) throws Exception assertTrue(run1.awaitFor(5, TimeUnit.SECONDS)); assertEquals(0, run1.getExitValue()); - File webApp = distribution.resolveArtifact("org.eclipse.jetty.tests:test-websocket-client-webapp:war:" + jettyVersion); + File webApp = distribution.resolveArtifact("org.eclipse.jetty.tests:test-websocket-client-provided-webapp:war:" + jettyVersion); distribution.installWarFile(webApp, "test"); int port = distribution.freePort(); @@ -339,12 +335,6 @@ public void testWebsocketClientInWebapp(String scheme) throws Exception "jetty.http.port=" + port, "jetty.ssl.port=" + port, // "jetty.server.dumpAfterStart=true", - // "jetty.webapp.addSystemClasses+=,org.eclipse.jetty.client.", - // "jetty.webapp.addServerClasses+=,-org.eclipse.jetty.client.", - // "jetty.webapp.addSystemClasses+=,org.eclipse.jetty.util.ssl.", - // "jetty.webapp.addServerClasses+=,-org.eclipse.jetty.util.ssl.", - // "jetty.webapp.addSystemClasses+=,org.eclipse.jetty.util.component.", - // "jetty.webapp.addServerClasses+=,-org.eclipse.jetty.util.component." }; try (DistributionTester.Run run2 = distribution.start(args2)) @@ -365,38 +355,53 @@ public void testWebsocketClientInWebapp(String scheme) throws Exception } } - public static class WsListener implements WebSocketListener + @ParameterizedTest + @ValueSource(strings = {"http", "https"}) + public void testWebsocketClientInWebapp(String scheme) throws Exception { - public BlockingArrayQueue textMessages = new BlockingArrayQueue<>(); - public final CountDownLatch closeLatch = new CountDownLatch(1); - public int closeCode; + Path jettyBase = Files.createTempDirectory("jetty_base"); + String jettyVersion = System.getProperty("jettyVersion"); + DistributionTester distribution = DistributionTester.Builder.newInstance() + .jettyVersion(jettyVersion) + .jettyBase(jettyBase) + .mavenLocalRepository(System.getProperty("mavenRepoPath")) + .build(); - @Override - public void onWebSocketClose(int statusCode, String reason) + String[] args1 = { + "--create-startd", + "--approve-all-licenses", + "--add-to-start=resources,server,webapp,deploy,jsp,jmx,servlet,servlets,websocket," + scheme + }; + try (DistributionTester.Run run1 = distribution.start(args1)) { - this.closeCode = statusCode; - closeLatch.countDown(); - } + assertTrue(run1.awaitFor(5, TimeUnit.SECONDS)); + assertEquals(0, run1.getExitValue()); - @Override - public void onWebSocketConnect(Session session) - { - } + File webApp = distribution.resolveArtifact("org.eclipse.jetty.tests:test-websocket-client-webapp:war:" + jettyVersion); + distribution.installWarFile(webApp, "test"); - @Override - public void onWebSocketError(Throwable cause) - { - } + int port = distribution.freePort(); + String[] args2 = { + "jetty.http.port=" + port, + "jetty.ssl.port=" + port, + "jetty.webapp.addServerClasses+=,+org.eclipse.jetty.websocket.", + "jetty.webapp.addSystemClasses+=,-org.eclipse.jetty.websocket.", + // "jetty.server.dumpAfterStart=true", + }; - @Override - public void onWebSocketBinary(byte[] payload, int offset, int len) - { - } + try (DistributionTester.Run run2 = distribution.start(args2)) + { + assertTrue(run2.awaitConsoleLogsFor("Started @", 10, TimeUnit.SECONDS)); - @Override - public void onWebSocketText(String message) - { - textMessages.add(message); + // We should get the correct configuration from the jetty-websocket-httpclient.xml file. + startHttpClient(scheme.equals("https")); + URI serverUri = URI.create(scheme + "://localhost:" + port + "/test"); + ContentResponse response = client.GET(serverUri); + assertEquals(HttpStatus.OK_200, response.getStatus()); + String content = response.getContentAsString(); + assertThat(content, containsString("WebSocketEcho: success")); + assertThat(content, containsString("ConnectTimeout: 4999")); + } } } } diff --git a/tests/test-webapps/pom.xml b/tests/test-webapps/pom.xml index a515d4e121a2..94f4b2387772 100644 --- a/tests/test-webapps/pom.xml +++ b/tests/test-webapps/pom.xml @@ -44,5 +44,6 @@ test-weld-cdi-webapp test-owb-cdi-webapp test-websocket-client-webapp + test-websocket-client-provided-webapp diff --git a/tests/test-webapps/test-websocket-client-provided-webapp/pom.xml b/tests/test-webapps/test-websocket-client-provided-webapp/pom.xml new file mode 100644 index 000000000000..81511e0bd0b1 --- /dev/null +++ b/tests/test-webapps/test-websocket-client-provided-webapp/pom.xml @@ -0,0 +1,33 @@ + + + + org.eclipse.jetty.tests + test-webapps-parent + 9.4.33-SNAPSHOT + + + 4.0.0 + test-websocket-client-provided-webapp + war + + Test :: Jetty Websocket Simple Webapp with WebSocketClient + + + + javax.servlet + javax.servlet-api + provided + + + javax.websocket + javax.websocket-api + provided + + + org.eclipse.jetty.websocket + websocket-client + ${project.version} + provided + + + diff --git a/tests/test-webapps/test-websocket-client-provided-webapp/src/main/java/org/eclipse/jetty/tests/webapp/websocket/EchoEndpoint.java b/tests/test-webapps/test-websocket-client-provided-webapp/src/main/java/org/eclipse/jetty/tests/webapp/websocket/EchoEndpoint.java new file mode 100644 index 000000000000..2120c5d7cca3 --- /dev/null +++ b/tests/test-webapps/test-websocket-client-provided-webapp/src/main/java/org/eclipse/jetty/tests/webapp/websocket/EchoEndpoint.java @@ -0,0 +1,32 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.tests.webapp.websocket; + +import javax.websocket.OnMessage; +import javax.websocket.server.ServerEndpoint; + +@ServerEndpoint(value = "/echo") +public class EchoEndpoint +{ + @OnMessage + public String echo(String message) + { + return message; + } +} diff --git a/tests/test-webapps/test-websocket-client-provided-webapp/src/main/java/org/eclipse/jetty/tests/webapp/websocket/WebSocketClientServlet.java b/tests/test-webapps/test-websocket-client-provided-webapp/src/main/java/org/eclipse/jetty/tests/webapp/websocket/WebSocketClientServlet.java new file mode 100644 index 000000000000..154b5cfe3bb0 --- /dev/null +++ b/tests/test-webapps/test-websocket-client-provided-webapp/src/main/java/org/eclipse/jetty/tests/webapp/websocket/WebSocketClientServlet.java @@ -0,0 +1,129 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.tests.webapp.websocket; + +import java.io.PrintWriter; +import java.net.URI; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jetty.websocket.api.Session; +import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; +import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; +import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; +import org.eclipse.jetty.websocket.api.annotations.WebSocket; +import org.eclipse.jetty.websocket.api.util.WSURI; +import org.eclipse.jetty.websocket.client.WebSocketClient; + +@WebServlet("/") +public class WebSocketClientServlet extends HttpServlet +{ + private WebSocketClient client; + + @Override + public void init() throws ServletException + { + // We must rely on jetty-websocket-httpclient.xml as we do not have access to server classes like HttpClient. + client = new WebSocketClient(); + + try + { + client.start(); + } + catch (Exception e) + { + throw new ServletException(e); + } + } + + @Override + public void destroy() + { + try + { + client.stop(); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + { + try + { + resp.setContentType("text/html"); + + // Send and receive a websocket echo on the same server. + ClientSocket clientSocket = new ClientSocket(); + URI wsUri = WSURI.toWebsocket(req.getRequestURL()).resolve("echo"); + client.connect(clientSocket, wsUri).get(5, TimeUnit.SECONDS); + clientSocket.session.getRemote().sendString("test message"); + String response = clientSocket.textMessages.poll(5, TimeUnit.SECONDS); + clientSocket.session.close(); + clientSocket.closeLatch.await(5, TimeUnit.SECONDS); + + PrintWriter writer = resp.getWriter(); + writer.println("WebSocketEcho: " + ("test message".equals(response) ? "success" : "failure")); + writer.println("WebSocketEcho: success"); + // We cannot test the HttpClient timeout because it is a server class not exposed to the webapp. + // writer.println("ConnectTimeout: " + client.getHttpClient().getConnectTimeout()); + } + catch (Exception e) + { + throw new RuntimeException(e); + } + } + + @WebSocket + public static class ClientSocket + { + public Session session; + public CountDownLatch openLatch = new CountDownLatch(1); + public CountDownLatch closeLatch = new CountDownLatch(1); + public ArrayBlockingQueue textMessages = new ArrayBlockingQueue<>(10); + + @OnWebSocketConnect + public void onOpen(Session session) + { + this.session = session; + openLatch.countDown(); + } + + @OnWebSocketMessage + public void onMessage(String message) + { + textMessages.add(message); + } + + @OnWebSocketClose + public void onClose(int statusCode, String reason) + { + closeLatch.countDown(); + } + } +} diff --git a/tests/test-webapps/test-websocket-client-webapp/src/main/resources/jetty-websocket-httpclient.xml b/tests/test-webapps/test-websocket-client-provided-webapp/src/main/resources/jetty-websocket-httpclient.xml similarity index 100% rename from tests/test-webapps/test-websocket-client-webapp/src/main/resources/jetty-websocket-httpclient.xml rename to tests/test-webapps/test-websocket-client-provided-webapp/src/main/resources/jetty-websocket-httpclient.xml diff --git a/tests/test-webapps/test-websocket-client-provided-webapp/src/main/webapp/WEB-INF/web.xml b/tests/test-webapps/test-websocket-client-provided-webapp/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 000000000000..99907fad52a3 --- /dev/null +++ b/tests/test-webapps/test-websocket-client-provided-webapp/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,8 @@ + + + diff --git a/tests/test-webapps/test-websocket-client-webapp/pom.xml b/tests/test-webapps/test-websocket-client-webapp/pom.xml index aedca8799288..ec8da2828928 100644 --- a/tests/test-webapps/test-websocket-client-webapp/pom.xml +++ b/tests/test-webapps/test-websocket-client-webapp/pom.xml @@ -27,7 +27,6 @@ org.eclipse.jetty.websocket websocket-client ${project.version} - provided diff --git a/tests/test-webapps/test-websocket-client-webapp/src/main/java/org/eclipse/jetty/tests/webapp/websocket/WebSocketClientServlet.java b/tests/test-webapps/test-websocket-client-webapp/src/main/java/org/eclipse/jetty/tests/webapp/websocket/WebSocketClientServlet.java index a26af3c8d1a6..36401a42e88c 100644 --- a/tests/test-webapps/test-websocket-client-webapp/src/main/java/org/eclipse/jetty/tests/webapp/websocket/WebSocketClientServlet.java +++ b/tests/test-webapps/test-websocket-client-webapp/src/main/java/org/eclipse/jetty/tests/webapp/websocket/WebSocketClientServlet.java @@ -29,6 +29,8 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; @@ -45,11 +47,15 @@ public class WebSocketClientServlet extends HttpServlet @Override public void init() throws ServletException { - client = new WebSocketClient(); + // We can't use the jetty-websocket-httpclient.xml if the websocket client jars are in WEB-INF/lib. + SslContextFactory.Client sslContextFactory = new SslContextFactory.Client(true); + HttpClient httpClient = new HttpClient(sslContextFactory); + httpClient.setConnectTimeout(4999); + this.client = new WebSocketClient(httpClient); try { - client.start(); + this.client.start(); } catch (Exception e) { @@ -89,8 +95,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) PrintWriter writer = resp.getWriter(); writer.println("WebSocketEcho: " + ("test message".equals(response) ? "success" : "failure")); writer.println("WebSocketEcho: success"); - // We cannot test the HttpClient timeout because it is a server class not exposed to the webapp. - // writer.println("ConnectTimeout: " + client.getHttpClient().getConnectTimeout()); + writer.println("ConnectTimeout: " + client.getHttpClient().getConnectTimeout()); } catch (Exception e) { @@ -125,10 +130,4 @@ public void onClose(int statusCode, String reason) closeLatch.countDown(); } } - - private void assertTrue(boolean value) - { - if (!value) - throw new RuntimeException("expected expression to be true but was false"); - } } From 59883af8bf554e0308c6047a8ddcf4bd462e2bcc Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Fri, 30 Oct 2020 15:00:38 +1100 Subject: [PATCH 09/10] update version to 9.4.34-SNAPSHOT Signed-off-by: Lachlan Roberts --- .../test-webapps/test-websocket-client-provided-webapp/pom.xml | 2 +- tests/test-webapps/test-websocket-client-webapp/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test-webapps/test-websocket-client-provided-webapp/pom.xml b/tests/test-webapps/test-websocket-client-provided-webapp/pom.xml index 81511e0bd0b1..9f57388e81ed 100644 --- a/tests/test-webapps/test-websocket-client-provided-webapp/pom.xml +++ b/tests/test-webapps/test-websocket-client-provided-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.33-SNAPSHOT + 9.4.34-SNAPSHOT 4.0.0 diff --git a/tests/test-webapps/test-websocket-client-webapp/pom.xml b/tests/test-webapps/test-websocket-client-webapp/pom.xml index ec8da2828928..d4e41a770eca 100644 --- a/tests/test-webapps/test-websocket-client-webapp/pom.xml +++ b/tests/test-webapps/test-websocket-client-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.33-SNAPSHOT + 9.4.34-SNAPSHOT 4.0.0 From 60c56d885640db4588816b04c26e48e985f8bbd8 Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Mon, 2 Nov 2020 23:43:42 +1100 Subject: [PATCH 10/10] changes from review Signed-off-by: Lachlan Roberts --- .../client/XmlBasedHttpClientProvider.java | 8 +------- .../tests/distribution/DistributionTests.java | 5 ++--- .../src/test/resources/keystore | Bin 1426 -> 0 bytes .../webapp/websocket/WebSocketClientServlet.java | 10 +++++++--- 4 files changed, 10 insertions(+), 13 deletions(-) delete mode 100644 tests/test-distribution/src/test/resources/keystore diff --git a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/XmlBasedHttpClientProvider.java b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/XmlBasedHttpClientProvider.java index 93e347c66c9e..b93f0f3bb89c 100644 --- a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/XmlBasedHttpClientProvider.java +++ b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/XmlBasedHttpClientProvider.java @@ -46,16 +46,10 @@ public static HttpClient get(@SuppressWarnings("unused") WebSocketContainerScope Thread.currentThread().setContextClassLoader(HttpClient.class.getClassLoader()); return newHttpClient(resource); } - catch (Throwable t) - { - LOG.warn("Failure to load HttpClient from XML", t); - } finally { Thread.currentThread().setContextClassLoader(contextClassLoader); } - - return null; } private static HttpClient newHttpClient(URL resource) @@ -67,7 +61,7 @@ private static HttpClient newHttpClient(URL resource) } catch (Throwable t) { - LOG.warn("Unable to load: {}", resource, t); + LOG.warn("Failure to load HttpClient from XML {}", resource, t); } return null; diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java index 961c60c5e80e..d89185bda5db 100644 --- a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java +++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java @@ -351,9 +351,7 @@ public void testWebsocketClientInWebappProvidedByServer(String scheme) throws Ex assertEquals(HttpStatus.OK_200, response.getStatus()); String content = response.getContentAsString(); assertThat(content, containsString("WebSocketEcho: success")); - - // We cannot test the HttpClient timeout because it is a server class not exposed to the webapp. - // assertThat(content, containsString("ConnectTimeout: 4999")); + assertThat(content, containsString("ConnectTimeout: 4999")); } } } @@ -387,6 +385,7 @@ public void testWebsocketClientInWebapp(String scheme) throws Exception String[] args2 = { "jetty.http.port=" + port, "jetty.ssl.port=" + port, + // We must hide the websocket classes from the webapp if we are to include websocket client jars in WEB-INF/lib. "jetty.webapp.addServerClasses+=,+org.eclipse.jetty.websocket.", "jetty.webapp.addSystemClasses+=,-org.eclipse.jetty.websocket.", // "jetty.server.dumpAfterStart=true", diff --git a/tests/test-distribution/src/test/resources/keystore b/tests/test-distribution/src/test/resources/keystore deleted file mode 100644 index b727bd0fb777fddb3463c81cb56963a7541f7b45..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1426 zcmezO_TO6u1_mY|W&~r_+{*0KN+9!5EW=$#pv*3VCZ=r$d~96WY>X_7T1LX-9cnmv_92vyZY^nksPD zdgGz_%YMiA%<+G`?zc{_^OTmKsam}GdFt7neK!{P|Bco8Yq|9PvTGT0HqQC!@x9l1 z+kfrLjk$U4PfrzX4>?lEY_X)NU`c_upzVKwLzZV_Z=OB7;%H;~#q=-kB7C15mGAK^ zvQDWpwV1Q=%|)J*vS+h8eD_X&KBLa;y!Ym4fd?y?u6<@yiQRcgW4YSWJ1qI-Q@4qE za4m1Vxao>O&#^E1)!s>&+m1~AFk#ErRgE9c$R|1RHZn>ST)F2PCX`h;GftH|P3C*s zWzB^ZGW^U2Io6G9jl> z6zzz+mrM40Funf&SL@T49sAWnZvUNcc-}kaM`;+(`I*O}e=OTwz2vdB%C^t0KV2dN z8|5bLIJC=m`3p1S>EdUM&gly9o_)k?62R=&u_P~(KYzPEv+V7u$GBF7Yt*targsEg zTQzgVqnKmgxtO%H)!0fto_uWX^v1c;QdM?#toT{0*tgvCKBx=r`VraapZ2`+cgggB z-Pvqw9={ifyv(DLz=%jkh_cpEkNBn#fQtx!K-V#22ApgPb-K(wNrdO3Et=(zk zH%r#4Uj9|=lZlRA5;d`xvpUaban7~tb)L?vqO(?31t6P_KXXUmI|NTdEW^*XD%W$kc6J6C`ZJL_TRc(ux#yKj=Ue_0-Rb!XA^BcIEU@^esCUfRc7B*q_(7f!t{PH}Q2nU7; zJ3>UpKnkRbOIX-9zos$!bwcyY3l3?6uy+&YLB9AjrXwMJ9=TVxnh^gTTRrgQDAx z_HixoIbPSC|G?I^w5omSz6+C2WR&Q742Af!tZ{F_B0c(^#Lh& zza|JWF*7nSB0CQl;mkmH*$SFDWnY}}>VU(o3#<5V+huGG`Dn2??1_qdd2)==i--F? zs#KSqOx?Wrm7jRA(!0Yuu5HVhrWZZce5Lb}5Bq8!uvR=V-JM%7`INM|?JE9h{&PR9 zPS5OYv=7|qeAeX{<0}8%Th2N96wN*x(D1*r!0!3JEkDAd&tKmoUZ_-IpH*z9SS