diff --git a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/ClientContainer.java b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/ClientContainer.java
index 5c39692c032..97986c6576f 100644
--- a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/ClientContainer.java
+++ b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/ClientContainer.java
@@ -325,6 +325,12 @@ public class ClientContainer extends ContainerLifeCycle implements WebSocketCont
         return client;
     }
 
+    @Override
+    public ClassLoader getClassLoader()
+    {
+        return client.getClassLoader();
+    }
+
     public EndpointMetadata getClientEndpointMetadata(Class<?> endpoint, EndpointConfig config)
     {
         synchronized (endpointClientMetadataCache)
diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/JavaxClientClassLoaderTest.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/JavaxClientClassLoaderTest.java
index e9fd67e631c..7c0788aaa6e 100644
--- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/JavaxClientClassLoaderTest.java
+++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/JavaxClientClassLoaderTest.java
@@ -1,14 +1,19 @@
 //
-// ========================================================================
-// Copyright (c) 1995-2021 Mort Bay Consulting Pty Ltd and others.
+//  ========================================================================
+//  Copyright (c) 1995-2021 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.
 //
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License v. 2.0 which is available at
-// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
 //
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-// ========================================================================
+//      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.websocket.jsr356.server;
@@ -35,6 +40,8 @@ import org.eclipse.jetty.http.BadMessageException;
 import org.eclipse.jetty.http.HttpStatus;
 import org.eclipse.jetty.io.ByteBufferPool;
 import org.eclipse.jetty.util.component.ContainerLifeCycle;
+import org.eclipse.jetty.webapp.WebAppContext;
+import org.eclipse.jetty.websocket.client.WebSocketClient;
 import org.eclipse.jetty.websocket.common.WebSocketSession;
 import org.eclipse.jetty.websocket.jsr356.ClientContainer;
 import org.eclipse.jetty.xml.XmlConfiguration;
@@ -48,7 +55,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
 
 public class JavaxClientClassLoaderTest
 {
-    private WebAppTester server;
+    private final WebAppTester server = new WebAppTester();
     private HttpClient httpClient;
 
     @FunctionalInterface
@@ -59,7 +66,6 @@ public class JavaxClientClassLoaderTest
 
     public void start(ThrowingRunnable configuration) throws Exception
     {
-        server = new WebAppTester();
         configuration.run();
         server.start();
         httpClient = new HttpClient();
@@ -129,13 +135,18 @@ public class JavaxClientClassLoaderTest
 
     public WebAppTester.WebApp createWebSocketWebapp(String contextName) throws Exception
     {
-        WebAppTester.WebApp app = server.createWebApp(contextName);
+        WebAppTester.WebApp app = this.server.createWebApp(contextName);
+
+        // We must hide the websocket classes from the webapp if we are to include websocket client jars in WEB-INF/lib.
+        WebAppContext context = app.getWebAppContext();
+        context.getServerClasspathPattern().include("org.eclipse.jetty.websocket.");
+        context.getSystemClasspathPattern().exclude("org.eclipse.jetty.websocket.");
 
         // Copy over the individual jars required for Javax WebSocket.
         app.createWebInf();
         app.copyLib(WebSocketContainer.class, "websocket-javax-api.jar");
-        app.copyLib(ServerContainer.class, "websocket-javax-server.jar");
         app.copyLib(ClientContainer.class, "websocket-javax-client.jar");
+        app.copyLib(WebSocketClient.class, "websocket-jetty-client.jar");
         app.copyLib(WebSocketSession.class, "websocket-common.jar");
         app.copyLib(ContainerLifeCycle.class, "jetty-util.jar");
         app.copyLib(Response.class, "jetty-client.jar");
@@ -158,7 +169,6 @@ public class JavaxClientClassLoaderTest
             app1.deploy();
 
             WebAppTester.WebApp app2 = server.createWebApp("/echo");
-            app2.getWebAppContext().setAttribute("org.eclipse.jetty.websocket.jsr356", Boolean.TRUE);
             app2.createWebInf();
             app2.copyClass(EchoSocket.class);
             app2.deploy();
@@ -189,7 +199,6 @@ public class JavaxClientClassLoaderTest
 
             // Do not exclude JavaxWebSocketConfiguration for this webapp (we need the websocket server classes).
             WebAppTester.WebApp app2 = server.createWebApp("/echo");
-            app2.getWebAppContext().setAttribute("org.eclipse.jetty.websocket.jsr356", Boolean.TRUE);
             app2.createWebInf();
             app2.copyClass(EchoSocket.class);
             app2.deploy();
diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/WebAppTester.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/WebAppTester.java
index a269540b09c..e749fd20236 100644
--- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/WebAppTester.java
+++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/WebAppTester.java
@@ -1,14 +1,19 @@
 //
-// ========================================================================
-// Copyright (c) 1995-2021 Mort Bay Consulting Pty Ltd and others.
+//  ========================================================================
+//  Copyright (c) 1995-2021 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.
 //
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License v. 2.0 which is available at
-// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
 //
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-// ========================================================================
+//      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.websocket.jsr356.server;
diff --git a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java
index d7e5f9b35ce..b1af999b1d0 100644
--- a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java
+++ b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java
@@ -76,6 +76,7 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont
     private final Supplier<DecoratedObjectFactory> objectFactorySupplier;
 
     // WebSocket Specifics
+    private final ClassLoader classloader;
     private final WebSocketPolicy policy;
     private final WebSocketExtensionFactory extensionRegistry;
     private final SessionTracker sessionTracker = new SessionTracker();
@@ -112,6 +113,7 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont
      */
     public WebSocketClient(HttpClient httpClient, DecoratedObjectFactory decoratedObjectFactory)
     {
+        this.classloader = Thread.currentThread().getContextClassLoader();
         this.httpClient = Objects.requireNonNull(httpClient, "HttpClient");
 
         addBean(httpClient);
@@ -262,6 +264,7 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont
      */
     public WebSocketClient(final WebSocketContainerScope scope, EventDriverFactory eventDriverFactory, SessionFactory sessionFactory, HttpClient httpClient)
     {
+        this.classloader = Thread.currentThread().getContextClassLoader();
         this.httpClient = httpClient == null ? HttpClientProvider.get(scope) : httpClient;
         addBean(this.httpClient);
 
@@ -386,6 +389,12 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont
         return wsReq.sendAsync();
     }
 
+    @Override
+    public ClassLoader getClassLoader()
+    {
+        return classloader;
+    }
+
     public void setEventDriverFactory(EventDriverFactory eventDriverFactory)
     {
         this.eventDriverFactory = eventDriverFactory;
diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSession.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSession.java
index 01295dad9c6..a19e3800a16 100644
--- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSession.java
+++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSession.java
@@ -73,12 +73,12 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Rem
     private final WebSocketPolicy policy;
     private final AtomicBoolean onCloseCalled = new AtomicBoolean(false);
     private final RemoteEndpointFactory remoteEndpointFactory;
-    private ClassLoader classLoader;
+    private final ClassLoader classLoader;
     private ExtensionFactory extensionFactory;
     private String protocolVersion;
-    private Map<String, String[]> parameterMap = new HashMap<>();
+    private final Map<String, String[]> parameterMap = new HashMap<>();
     private RemoteEndpoint remote;
-    private IncomingFrames incomingHandler;
+    private final IncomingFrames incomingHandler;
     private OutgoingFrames outgoingHandler;
     private UpgradeRequest upgradeRequest;
     private UpgradeResponse upgradeResponse;
@@ -98,7 +98,7 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Rem
         Objects.requireNonNull(containerScope, "Container Scope cannot be null");
         Objects.requireNonNull(requestURI, "Request URI cannot be null");
 
-        this.classLoader = Thread.currentThread().getContextClassLoader();
+        this.classLoader = containerScope.getClassLoader();
         this.containerScope = containerScope;
         this.requestURI = requestURI;
         this.websocket = websocket;
diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/scopes/WebSocketContainerScope.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/scopes/WebSocketContainerScope.java
index f8dc15b0b69..b2111a7d480 100644
--- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/scopes/WebSocketContainerScope.java
+++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/scopes/WebSocketContainerScope.java
@@ -67,6 +67,20 @@ public interface WebSocketContainerScope
      */
     SslContextFactory getSslContextFactory();
 
+    /**
+     * <p>The ClassLoader used to load classes for the WebSocketSession.</p>
+     * <p>By default this will be the ContextClassLoader at the time this method is called. However this will be overridden
+     * by the WebSocketClient to use the ContextClassLoader at the time it was created, this is because the
+     * client uses its own {@link org.eclipse.jetty.util.thread.ThreadPool} so the WebSocketSessions may be created when
+     * the ContextClassLoader is not set.</p>
+     *
+     * @return the classloader.
+     */
+    default ClassLoader getClassLoader()
+    {
+        return Thread.currentThread().getContextClassLoader();
+    }
+
     /**
      * Test for if the container has been started.
      *