442495 - Bad Context ClassLoader in JSR356 WebSocket onOpen
+ Fixing onOpen context classloader to be that of the context that started the WebSocketUpgradeFilter (which will be the same as the WebAppContext in most cases)
This commit is contained in:
parent
901707b894
commit
0bf68a07ae
|
@ -131,8 +131,13 @@ public class WebSocketServerContainerInitializer implements ServletContainerInit
|
||||||
|
|
||||||
ServletContextHandler jettyContext = (ServletContextHandler)handler;
|
ServletContextHandler jettyContext = (ServletContextHandler)handler;
|
||||||
|
|
||||||
|
ClassLoader old = Thread.currentThread().getContextClassLoader();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Thread.currentThread().setContextClassLoader(context.getClassLoader());
|
||||||
|
|
||||||
// Create the Jetty ServerContainer implementation
|
// Create the Jetty ServerContainer implementation
|
||||||
ServerContainer jettyContainer = configureContext(context, jettyContext);
|
ServerContainer jettyContainer = configureContext(context,jettyContext);
|
||||||
|
|
||||||
// Store a reference to the ServerContainer per javax.websocket spec 1.0 final section 6.4 Programmatic Server Deployment
|
// Store a reference to the ServerContainer per javax.websocket spec 1.0 final section 6.4 Programmatic Server Deployment
|
||||||
context.setAttribute(javax.websocket.server.ServerContainer.class.getName(),jettyContainer);
|
context.setAttribute(javax.websocket.server.ServerContainer.class.getName(),jettyContainer);
|
||||||
|
@ -231,6 +236,9 @@ public class WebSocketServerContainerInitializer implements ServletContainerInit
|
||||||
throw new ServletException(e);
|
throw new ServletException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
Thread.currentThread().setContextClassLoader(old);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
|
|
@ -61,6 +61,7 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Inc
|
||||||
private final LogicalConnection connection;
|
private final LogicalConnection connection;
|
||||||
private final SessionListener[] sessionListeners;
|
private final SessionListener[] sessionListeners;
|
||||||
private final Executor executor;
|
private final Executor executor;
|
||||||
|
private ClassLoader classLoader;
|
||||||
private ExtensionFactory extensionFactory;
|
private ExtensionFactory extensionFactory;
|
||||||
private String protocolVersion;
|
private String protocolVersion;
|
||||||
private Map<String, String[]> parameterMap = new HashMap<>();
|
private Map<String, String[]> parameterMap = new HashMap<>();
|
||||||
|
@ -78,6 +79,7 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Inc
|
||||||
throw new RuntimeException("Request URI cannot be null");
|
throw new RuntimeException("Request URI cannot be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.classLoader = Thread.currentThread().getContextClassLoader();
|
||||||
this.requestURI = requestURI;
|
this.requestURI = requestURI;
|
||||||
this.websocket = websocket;
|
this.websocket = websocket;
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
|
@ -183,6 +185,11 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Inc
|
||||||
return this.connection.getBufferPool();
|
return this.connection.getBufferPool();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ClassLoader getClassLoader()
|
||||||
|
{
|
||||||
|
return this.getClass().getClassLoader();
|
||||||
|
}
|
||||||
|
|
||||||
public LogicalConnection getConnection()
|
public LogicalConnection getConnection()
|
||||||
{
|
{
|
||||||
return connection;
|
return connection;
|
||||||
|
@ -394,14 +401,16 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Inc
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ClassLoader old = Thread.currentThread().getContextClassLoader();
|
||||||
|
try {
|
||||||
|
Thread.currentThread().setContextClassLoader(classLoader);
|
||||||
|
|
||||||
// Upgrade success
|
// Upgrade success
|
||||||
connection.getIOState().onConnected();
|
connection.getIOState().onConnected();
|
||||||
|
|
||||||
// Connect remote
|
// Connect remote
|
||||||
remote = new WebSocketRemoteEndpoint(connection,outgoingHandler,getBatchMode());
|
remote = new WebSocketRemoteEndpoint(connection,outgoingHandler,getBatchMode());
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Open WebSocket
|
// Open WebSocket
|
||||||
websocket.openSession(this);
|
websocket.openSession(this);
|
||||||
|
|
||||||
|
@ -425,6 +434,10 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Inc
|
||||||
|
|
||||||
close(statusCode,t.getMessage());
|
close(statusCode,t.getMessage());
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Thread.currentThread().setContextClassLoader(old);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setExtensionFactory(ExtensionFactory extensionFactory)
|
public void setExtensionFactory(ExtensionFactory extensionFactory)
|
||||||
|
@ -506,4 +519,5 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Inc
|
||||||
builder.append("]");
|
builder.append("]");
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.CopyOnWriteArraySet;
|
import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
@ -70,6 +71,7 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc
|
||||||
{
|
{
|
||||||
private static final Logger LOG = Log.getLogger(WebSocketServerFactory.class);
|
private static final Logger LOG = Log.getLogger(WebSocketServerFactory.class);
|
||||||
|
|
||||||
|
private final ClassLoader contextClassloader;
|
||||||
private final Map<Integer, WebSocketHandshake> handshakes = new HashMap<>();
|
private final Map<Integer, WebSocketHandshake> handshakes = new HashMap<>();
|
||||||
/**
|
/**
|
||||||
* Have the factory maintain 1 and only 1 scheduler. All connections share this scheduler.
|
* Have the factory maintain 1 and only 1 scheduler. All connections share this scheduler.
|
||||||
|
@ -107,6 +109,8 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc
|
||||||
addBean(scheduler);
|
addBean(scheduler);
|
||||||
addBean(bufferPool);
|
addBean(bufferPool);
|
||||||
|
|
||||||
|
this.contextClassloader = Thread.currentThread().getContextClassLoader();
|
||||||
|
|
||||||
this.registeredSocketClasses = new ArrayList<>();
|
this.registeredSocketClasses = new ArrayList<>();
|
||||||
|
|
||||||
this.defaultPolicy = policy;
|
this.defaultPolicy = policy;
|
||||||
|
@ -151,8 +155,10 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc
|
||||||
@Override
|
@Override
|
||||||
public boolean acceptWebSocket(WebSocketCreator creator, HttpServletRequest request, HttpServletResponse response) throws IOException
|
public boolean acceptWebSocket(WebSocketCreator creator, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||||
{
|
{
|
||||||
|
ClassLoader old = Thread.currentThread().getContextClassLoader();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
Thread.currentThread().setContextClassLoader(contextClassloader);
|
||||||
ServletUpgradeRequest sockreq = new ServletUpgradeRequest(request);
|
ServletUpgradeRequest sockreq = new ServletUpgradeRequest(request);
|
||||||
ServletUpgradeResponse sockresp = new ServletUpgradeResponse(response);
|
ServletUpgradeResponse sockresp = new ServletUpgradeResponse(response);
|
||||||
|
|
||||||
|
@ -182,6 +188,10 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc
|
||||||
{
|
{
|
||||||
throw new IOException("Unable to accept websocket due to mangled URI", e);
|
throw new IOException("Unable to accept websocket due to mangled URI", e);
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Thread.currentThread().setContextClassLoader(old);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addSessionFactory(SessionFactory sessionFactory)
|
public void addSessionFactory(SessionFactory sessionFactory)
|
||||||
|
|
|
@ -91,10 +91,7 @@ public class WebSocketUpgradeFilter extends ContainerLifeCycle implements Filter
|
||||||
String pathSpec = "/*";
|
String pathSpec = "/*";
|
||||||
EnumSet<DispatcherType> dispatcherTypes = EnumSet.of(DispatcherType.REQUEST);
|
EnumSet<DispatcherType> dispatcherTypes = EnumSet.of(DispatcherType.REQUEST);
|
||||||
boolean isMatchAfter = false;
|
boolean isMatchAfter = false;
|
||||||
String urlPatterns[] =
|
String urlPatterns[] = { pathSpec };
|
||||||
{
|
|
||||||
pathSpec
|
|
||||||
};
|
|
||||||
|
|
||||||
FilterRegistration.Dynamic dyn = context.addFilter(name,filter);
|
FilterRegistration.Dynamic dyn = context.addFilter(name,filter);
|
||||||
dyn.addMappingForUrlPatterns(dispatcherTypes,isMatchAfter,urlPatterns);
|
dyn.addMappingForUrlPatterns(dispatcherTypes,isMatchAfter,urlPatterns);
|
||||||
|
|
Loading…
Reference in New Issue