From d6015606ea1f857aede7283914c4d7c1ea513b3d Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Thu, 11 Jan 2024 11:16:30 -0600 Subject: [PATCH] Issue #11260 - Allow `QuickStartConfiguration` to be used in mixed contexts environment where some do not have a WEB-INF/quickstart-web.xml Signed-off-by: Joakim Erdfelt --- .../quickstart/QuickStartConfiguration.java | 73 ++++++++++++------- .../jetty/quickstart/QuickStartTest.java | 37 ++++++++++ .../src/test/webapps/no-web-xml/index.html | 1 + 3 files changed, 84 insertions(+), 27 deletions(-) create mode 100644 tests/test-quickstart/src/test/webapps/no-web-xml/index.html diff --git a/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartConfiguration.java b/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartConfiguration.java index d7a4641abcd..db47e2b536d 100644 --- a/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartConfiguration.java +++ b/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartConfiguration.java @@ -48,6 +48,7 @@ public class QuickStartConfiguration extends AbstractConfiguration public static final String ORIGIN_ATTRIBUTE = "org.eclipse.jetty.quickstart.origin"; public static final String QUICKSTART_WEB_XML = "org.eclipse.jetty.quickstart.xml"; public static final String MODE = "org.eclipse.jetty.quickstart.mode"; + public static final String QUICKSTART_ENABLED = "org.eclipse.jetty.quickstart.enabled"; static { @@ -77,7 +78,6 @@ public class QuickStartConfiguration extends AbstractConfiguration } private Mode _mode = Mode.AUTO; - private boolean _quickStart; public QuickStartConfiguration() { @@ -86,6 +86,14 @@ public class QuickStartConfiguration extends AbstractConfiguration addDependents(WebXmlConfiguration.class); } + private boolean isQuickStartEnabled(WebAppContext context) + { + Boolean enabled = (Boolean)context.getAttribute(QUICKSTART_ENABLED); + if (enabled == null) + return true; // default is true + return enabled; + } + @Override public void preConfigure(WebAppContext context) throws Exception { @@ -102,9 +110,10 @@ public class QuickStartConfiguration extends AbstractConfiguration Mode mode = (Mode)context.getAttribute(MODE); if (mode != null) _mode = mode; - - _quickStart = false; - + + // disable quickstart for this context (it is only enabled if AUTO or QUICKSTART mode succeeds) + context.setAttribute(QUICKSTART_ENABLED, false); + switch (_mode) { case GENERATE: @@ -139,7 +148,9 @@ public class QuickStartConfiguration extends AbstractConfiguration if (quickStartWebXml.exists()) quickStart(context); else - throw new IllegalStateException("No " + quickStartWebXml); + { + LOG.warn("Skipping {} for {} as it does not contain {}", this.getClass().getName(), context, quickStartWebXml); + } break; default: @@ -160,37 +171,42 @@ public class QuickStartConfiguration extends AbstractConfiguration @Override public void configure(WebAppContext context) throws Exception { - if (!_quickStart) + if (!isQuickStartEnabled(context)) { - super.configure(context); + return; } - else - { - //add the processor to handle normal web.xml content - context.getMetaData().addDescriptorProcessor(new StandardDescriptorProcessor()); - //add a processor to handle extended web.xml format - context.getMetaData().addDescriptorProcessor(new QuickStartDescriptorProcessor()); + //add the processor to handle normal web.xml content + context.getMetaData().addDescriptorProcessor(new StandardDescriptorProcessor()); - //add a decorator that will find introspectable annotations - context.getObjectFactory().addDecorator(new AnnotationDecorator(context)); //this must be the last Decorator because they are run in reverse order! + //add a processor to handle extended web.xml format + context.getMetaData().addDescriptorProcessor(new QuickStartDescriptorProcessor()); - //add a context bean that will run ServletContainerInitializers as the context starts - ServletContainerInitializersStarter starter = (ServletContainerInitializersStarter)context.getAttribute(AnnotationConfiguration.CONTAINER_INITIALIZER_STARTER); - if (starter != null) - throw new IllegalStateException("ServletContainerInitializersStarter already exists"); - starter = new ServletContainerInitializersStarter(context); - context.setAttribute(AnnotationConfiguration.CONTAINER_INITIALIZER_STARTER, starter); - context.addBean(starter, true); + //add a decorator that will find introspectable annotations + context.getObjectFactory().addDecorator(new AnnotationDecorator(context)); //this must be the last Decorator because they are run in reverse order! - LOG.debug("configured {}", this); - } + //add a context bean that will run ServletContainerInitializers as the context starts + ServletContainerInitializersStarter starter = (ServletContainerInitializersStarter)context.getAttribute(AnnotationConfiguration.CONTAINER_INITIALIZER_STARTER); + if (starter != null) + throw new IllegalStateException("ServletContainerInitializersStarter already exists"); + starter = new ServletContainerInitializersStarter(context); + context.setAttribute(AnnotationConfiguration.CONTAINER_INITIALIZER_STARTER, starter); + context.addBean(starter, true); + + LOG.debug("configured {}", this); } @Override public void postConfigure(WebAppContext context) throws Exception { - super.postConfigure(context); + if (!isQuickStartEnabled(context)) + { + super.postConfigure(context); + return; + } + + context.removeAttribute(QUICKSTART_ENABLED); + ServletContainerInitializersStarter starter = (ServletContainerInitializersStarter)context.getAttribute(AnnotationConfiguration.CONTAINER_INITIALIZER_STARTER); if (starter != null) { @@ -203,7 +219,7 @@ public class QuickStartConfiguration extends AbstractConfiguration throws Exception { LOG.info("Quickstarting {}", context); - _quickStart = true; + context.setAttribute(QUICKSTART_ENABLED, true); context.setConfigurations(context.getConfigurations().stream() .filter(c -> !__replacedConfigurations.contains(c.replaces()) && !__replacedConfigurations.contains(c.getClass())) .collect(Collectors.toList()).toArray(new Configuration[]{})); @@ -229,7 +245,10 @@ public class QuickStartConfiguration extends AbstractConfiguration if (webInf == null || !webInf.exists()) { File tmp = new File(context.getBaseResource().getFile(), "WEB-INF"); - tmp.mkdirs(); + if (!tmp.mkdirs()) + { + throw new IllegalStateException("Unable to create directory " + tmp); + } webInf = context.getWebInf(); } diff --git a/tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartTest.java b/tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartTest.java index 949fa80cf86..04af170f835 100644 --- a/tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartTest.java +++ b/tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartTest.java @@ -24,6 +24,8 @@ import org.eclipse.jetty.plus.webapp.EnvConfiguration; import org.eclipse.jetty.plus.webapp.PlusConfiguration; import org.eclipse.jetty.server.NetworkConnector; import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.toolchain.test.FS; +import org.eclipse.jetty.toolchain.test.MavenPaths; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.resource.PathResource; @@ -41,6 +43,41 @@ import static org.junit.jupiter.api.Assertions.assertTrue; public class QuickStartTest { + /** + * Test of an exploded webapp directory, no WEB-INF/quickstart-web.xml, + * with QuickStartConfiguration enabled. + */ + @Test + public void testExplodedWebAppDirNoWebXml() throws Exception + { + Path jettyHome = MavenPaths.targetDir(); + Path webappDir = MavenPaths.targetTestDir("no-web-xml"); + Path src = MavenPaths.projectBase().resolve("src/test/webapps/no-web-xml"); + FS.ensureEmpty(webappDir); + org.eclipse.jetty.toolchain.test.IO.copyDir(src, webappDir); + + System.setProperty("jetty.home", jettyHome.toString()); + + Server server = new Server(0); + + WebAppContext webapp = new WebAppContext(); + webapp.addConfiguration(new QuickStartConfiguration(), + new EnvConfiguration(), + new PlusConfiguration(), + new AnnotationConfiguration()); + webapp.setAttribute(QuickStartConfiguration.MODE, QuickStartConfiguration.Mode.QUICKSTART); + webapp.setWarResource(new PathResource(webappDir)); + webapp.setContextPath("/"); + server.setHandler(webapp); + server.start(); + + URL url = new URL("http://127.0.0.1:" + server.getBean(NetworkConnector.class).getLocalPort() + "/index.html"); + HttpURLConnection connection = (HttpURLConnection)url.openConnection(); + assertEquals(200, connection.getResponseCode()); + assertThat(IO.toString((InputStream)connection.getContent()), Matchers.containsString("

Contents of no-web-xml

")); + + server.stop(); + } @Test public void testStandardTestWar() throws Exception diff --git a/tests/test-quickstart/src/test/webapps/no-web-xml/index.html b/tests/test-quickstart/src/test/webapps/no-web-xml/index.html new file mode 100644 index 00000000000..199996b48c5 --- /dev/null +++ b/tests/test-quickstart/src/test/webapps/no-web-xml/index.html @@ -0,0 +1 @@ +

Contents of no-web-xml

\ No newline at end of file