From fcaac7e61030cb84a3f8df4849a8607c5158869c Mon Sep 17 00:00:00 2001 From: Denis Anisimov Date: Mon, 30 Nov 2020 15:52:27 +0300 Subject: [PATCH] fix: servlet context listener should handle all possible Vaadin contexts Fixes #5 --- .../support/OSGiVaadinInitialization.java | 21 ++++++++++++--- .../ServletContainerInitializerClasses.java | 18 ++++++++++++- .../flow/osgi/CustomContextBaseHrefIT.java | 26 +++++++++++++++++++ 3 files changed, 60 insertions(+), 5 deletions(-) create mode 100644 test-containers/felix-jetty/src/test/java/com/vaadin/flow/osgi/CustomContextBaseHrefIT.java diff --git a/flow-osgi/src/main/java/com/vaadin/flow/osgi/support/OSGiVaadinInitialization.java b/flow-osgi/src/main/java/com/vaadin/flow/osgi/support/OSGiVaadinInitialization.java index 21bd38d..33c29d7 100644 --- a/flow-osgi/src/main/java/com/vaadin/flow/osgi/support/OSGiVaadinInitialization.java +++ b/flow-osgi/src/main/java/com/vaadin/flow/osgi/support/OSGiVaadinInitialization.java @@ -60,8 +60,13 @@ */ @Component(immediate = true, service = { VaadinServiceInitListener.class, HttpSessionListener.class, - ServletContextListener.class }, scope = ServiceScope.SINGLETON, property = HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER - + "=true") + ServletContextListener.class }, scope = ServiceScope.SINGLETON, property = { + HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER + "=true", + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT + "=(&(" + + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + + "=*) (!(" + + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + + "=vaadinResourcesContext.*)))" }) public class OSGiVaadinInitialization implements VaadinServiceInitListener, HttpSessionListener, ServletContextListener { @@ -187,11 +192,18 @@ public void contextInitialized(ServletContextEvent event) { VaadinServletContext context = new VaadinServletContext(servletContext); // ensure the lookup is set into the context - context.getAttribute(Lookup.class, () -> new OsgiLookupImpl()); + Lookup lookup = context.getAttribute(Lookup.class, + () -> new OsgiLookupImpl()); Collection servlets = lookupAll(Servlet.class); for (Servlet servlet : servlets) { if (isUninitializedServlet(servlet)) { + ServletContext ctx = servlet.getServletConfig() + .getServletContext(); + if (new VaadinServletContext(ctx) + .getAttribute(Lookup.class) != lookup) { + continue; + } try { servlet.init(servlet.getServletConfig()); } catch (ServletException e) { @@ -250,7 +262,8 @@ private Optional getBundle(String symbolicName) { } private String generateUniqueContextName(String contextPath) { - String name = "vaadinContext." + sanitizeContextName(contextPath); + String name = "vaadinResourcesContext." + + sanitizeContextName(contextPath); Set contextNames = getAvailableContextNames(); if (contextNames.contains(name)) { int i = 1; diff --git a/flow-osgi/src/main/java/com/vaadin/flow/osgi/support/ServletContainerInitializerClasses.java b/flow-osgi/src/main/java/com/vaadin/flow/osgi/support/ServletContainerInitializerClasses.java index 2715220..099b234 100644 --- a/flow-osgi/src/main/java/com/vaadin/flow/osgi/support/ServletContainerInitializerClasses.java +++ b/flow-osgi/src/main/java/com/vaadin/flow/osgi/support/ServletContainerInitializerClasses.java @@ -39,6 +39,7 @@ import com.vaadin.flow.internal.ReflectTools; import com.vaadin.flow.internal.UsageStatistics; import com.vaadin.flow.router.HasErrorParameter; +import com.vaadin.flow.server.InvalidApplicationConfigurationException; import com.vaadin.flow.server.startup.ClassLoaderAwareServletContainerInitializer; import com.vaadin.flow.server.startup.DevModeInitializer; import com.vaadin.flow.server.startup.LookupInitializer; @@ -105,7 +106,22 @@ public boolean hasInitializers() { public void addScannedClasses( Map>> extenderClasses) { cachedClasses.putAll(extenderClasses); - contexts.forEach(this::resetContextInitializers); + List thrown = new ArrayList<>(); + for (ServletContext context : contexts) { + try { + resetContextInitializers(context); + } catch (InvalidApplicationConfigurationException exception) { + // don't stop context initializers processing for different + // context, instead initialize all the contexts and then throw + thrown.add(exception); + } + } + // Now if there was an exception throw it. + // This is a workaround for #9417 which causes an exception being thrown + // by VaadinAppShellInitializer in our ITs + if (!thrown.isEmpty()) { + throw thrown.get(0); + } } /** diff --git a/test-containers/felix-jetty/src/test/java/com/vaadin/flow/osgi/CustomContextBaseHrefIT.java b/test-containers/felix-jetty/src/test/java/com/vaadin/flow/osgi/CustomContextBaseHrefIT.java new file mode 100644 index 0000000..e2ecf32 --- /dev/null +++ b/test-containers/felix-jetty/src/test/java/com/vaadin/flow/osgi/CustomContextBaseHrefIT.java @@ -0,0 +1,26 @@ +/* + * Copyright 2000-2020 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.flow.osgi; + +import com.vaadin.flow.uitest.ui.BaseHrefIT; + +public class CustomContextBaseHrefIT extends BaseHrefIT { + + @Override + protected String getTestPath() { + return "/custom-test-context" + super.getTestPath(); + } +}