Skip to content

Commit

Permalink
Order WebSocket initializer before Faces one
Browse files Browse the repository at this point in the history
Signed-off-by: Arjan Tijms <arjan.tijms@omnifish.ee>
  • Loading branch information
arjantijms committed Jan 22, 2024
1 parent 484aed3 commit f1f4552
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/*
* Copyright (c) 2024 Contributors to Eclipse Foundation.
* Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
* Copyright 2004 The Apache Software Foundation
*
Expand Down Expand Up @@ -269,4 +270,5 @@ public final class Globals {
public static final String ISO_8859_1_ENCODING = "ISO-8859-1";

public static final String FACES_INITIALIZER = "com.sun.faces.config.FacesInitializer";
public static final String WEBSOCKET_INITIALIZER = "org.glassfish.tyrus.servlet.TyrusServletContainerInitializer";
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, 2023 Contributors to Eclipse Foundation.
* Copyright (c) 2021, 2024 Contributors to Eclipse Foundation.
* Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
* Copyright 2004 The Apache Software Foundation
*
Expand Down Expand Up @@ -66,6 +66,7 @@
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
Expand Down Expand Up @@ -181,6 +182,7 @@
import static org.apache.catalina.Globals.FACES_INITIALIZER;
import static org.apache.catalina.Globals.META_INF_RESOURCES;
import static org.apache.catalina.Globals.RESOURCES_ATTR;
import static org.apache.catalina.Globals.WEBSOCKET_INITIALIZER;
import static org.apache.catalina.LogFacade.*;
import static org.apache.catalina.core.Constants.DEFAULT_SERVLET_NAME;
import static org.apache.catalina.core.Constants.JSP_SERVLET_NAME;
Expand Down Expand Up @@ -4525,11 +4527,15 @@ protected void callServletContainerInitializers() throws LifecycleException {
// We have the list of initializers and the classes that satisfy
// the condition. Time to call the initializers
ServletContext ctxt = this.getServletContext();
for (var entry : initializerList.entrySet()) {

var initializerListOrdered = orderInitializers(initializerList);

for (var entry : initializerListOrdered) {
Class<? extends ServletContainerInitializer> initializer = entry.getKey();
if (isUseMyFaces() && FACES_INITIALIZER.equals(initializer.getName())) {
continue;
}

try {
log.log(FINE, "Calling ServletContainerInitializer [{0}] onStartup with classes {1} ",
new Object[] {initializer, entry.getValue()});
Expand All @@ -4549,6 +4555,40 @@ protected void callServletContainerInitializers() throws LifecycleException {
}
}

private LinkedList<Entry<Class<? extends ServletContainerInitializer>, Set<Class<?>>>> orderInitializers(Map<Class<? extends ServletContainerInitializer>, Set<Class<?>>> initializerList) {
Entry<Class<? extends ServletContainerInitializer>, Set<Class<?>>> facesInitializerEntry = null;
var initializerListOrdered = new LinkedList<>(initializerList.entrySet());
for (var iterator = initializerListOrdered.listIterator(); iterator.hasNext();) {
var initializerEntry = iterator.next();
Class<? extends ServletContainerInitializer> initializer = initializerEntry.getKey();

// Make sure the WEBSOCKET_INITIALIZER gets a chance to run before the FACES_INITIALIZER.
// This is because of a complicated interaction, where the WEBSOCKET_INITIALIZER
// is also executed by the FACES_INITIALIZER.
// If both have classes to process, the WEBSOCKET_INITIALIZER called by the FACES_INITIALIZER
// will create a container that will be later overwritten by the direct call to the
// WEBSOCKET_INITIALIZER.
// Ultimately this should be fixed in the WebSocket and Faces specs.
if (FACES_INITIALIZER.equals(initializer.getName())) {
facesInitializerEntry = initializerEntry;
iterator.remove();
} else if (WEBSOCKET_INITIALIZER.equals(initializer.getName())) {
if (facesInitializerEntry != null) {
iterator.add(facesInitializerEntry);
facesInitializerEntry = null;
}
break;
}
}

// Gather for the potential problem that a Faces initializer would be present
// but no WebSocket one.
if (facesInitializerEntry != null) {
initializerListOrdered.add(facesInitializerEntry);
}

return initializerListOrdered;
}

private List<ServletContainerInitializer> loadServletContainerInitializers() {
List<ServletContainerInitializer> initializers = new ArrayList<>();
Expand Down

0 comments on commit f1f4552

Please sign in to comment.