Issue #5320 - reproduce failure to load httpClient for WebSocketClient in webapp
Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
This commit is contained in:
parent
e3ed05fc1c
commit
00f05cb94e
|
@ -35,15 +35,13 @@ public final class HttpClientProvider
|
|||
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);
|
||||
|
|
|
@ -22,6 +22,7 @@ import java.net.URL;
|
|||
|
||||
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 @@ class XmlBasedHttpClientProvider
|
|||
{
|
||||
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)
|
||||
|
|
|
@ -102,6 +102,18 @@
|
|||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
<artifactId>websocket-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
<artifactId>websocket-client</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.tests</groupId>
|
||||
<artifactId>test-felix-webapp</artifactId>
|
||||
|
|
|
@ -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.HTTP2Client;
|
|||
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 class DistributionTests extends AbstractDistributionTest
|
|||
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<String> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,5 +44,6 @@
|
|||
<module>test-cdi-common-webapp</module>
|
||||
<module>test-weld-cdi-webapp</module>
|
||||
<module>test-owb-cdi-webapp</module>
|
||||
<module>test-websocket-client-webapp</module>
|
||||
</modules>
|
||||
</project>
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>org.eclipse.jetty.tests</groupId>
|
||||
<artifactId>test-webapps-parent</artifactId>
|
||||
<version>9.4.32-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>test-websocket-client-webapp</artifactId>
|
||||
<packaging>war</packaging>
|
||||
|
||||
<name>Test :: Jetty Websocket Simple Webapp with WebSocketClient</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.websocket</groupId>
|
||||
<artifactId>javax.websocket-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
<artifactId>websocket-client</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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<String> 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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
|
||||
<Configure class="org.eclipse.jetty.client.HttpClient">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.util.ssl.SslContextFactory$Client">
|
||||
<Set name="trustAll" type="java.lang.Boolean">false</Set>
|
||||
<Call name="addExcludeProtocols">
|
||||
<Arg>
|
||||
<Array type="java.lang.String">
|
||||
<Item>TLS/1.3</Item>
|
||||
</Array>
|
||||
</Arg>
|
||||
</Call>
|
||||
<Call name="setExcludeCipherSuites"><!-- websocket.org uses WEAK cipher suites -->
|
||||
<Arg>
|
||||
<Array type="java.lang.String" />
|
||||
</Arg>
|
||||
</Call>
|
||||
</New>
|
||||
</Arg>
|
||||
<Set name="connectTimeout">4999</Set>
|
||||
</Configure>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<web-app
|
||||
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
|
||||
metadata-complete="false"
|
||||
version="3.1">
|
||||
</web-app>
|
Loading…
Reference in New Issue