mirror of
https://github.com/jetty/jetty.project.git
synced 2025-02-24 00:17:18 +00:00
Merge pull request #2110 from eclipse/issue-1602-deployer-error
Issue #1602 - Deployment Error should fail fast
This commit is contained in:
commit
c9dd17bf9a
@ -74,6 +74,7 @@ public class AppLifeCycle extends Graph
|
||||
public static final String STARTED = "started";
|
||||
public static final String STOPPING = "stopping";
|
||||
public static final String UNDEPLOYING = "undeploying";
|
||||
public static final String FAILED = "failed";
|
||||
|
||||
|
||||
private Map<String, List<Binding>> lifecyclebindings = new HashMap<String, List<Binding>>();
|
||||
@ -97,6 +98,9 @@ public class AppLifeCycle extends Graph
|
||||
// deployed -> undeployed
|
||||
addEdge(DEPLOYED,UNDEPLOYING);
|
||||
addEdge(UNDEPLOYING,UNDEPLOYED);
|
||||
|
||||
// failed (unconnected)
|
||||
addNode(new Node(FAILED));
|
||||
}
|
||||
|
||||
public void addBinding(AppLifeCycle.Binding binding)
|
||||
|
@ -507,6 +507,18 @@ public class DeploymentManager extends ContainerLifeCycle
|
||||
catch (Throwable t)
|
||||
{
|
||||
LOG.warn("Unable to reach node goal: " + nodeName,t);
|
||||
// migrate to FAILED node
|
||||
Node failed = _lifecycle.getNodeByName(AppLifeCycle.FAILED);
|
||||
appentry.setLifeCycleNode(failed);
|
||||
try
|
||||
{
|
||||
_lifecycle.runBindings(failed, appentry.app, this);
|
||||
}
|
||||
catch (Throwable ignore)
|
||||
{
|
||||
// The runBindings failed for 'failed' node
|
||||
LOG.ignore(ignore);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@ import org.eclipse.jetty.deploy.App;
|
||||
import org.eclipse.jetty.deploy.AppLifeCycle;
|
||||
import org.eclipse.jetty.deploy.graph.Node;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
|
||||
|
||||
public class StandardStarter implements AppLifeCycle.Binding
|
||||
{
|
||||
@ -35,12 +36,17 @@ public class StandardStarter implements AppLifeCycle.Binding
|
||||
@Override
|
||||
public void processBinding(Node node, App app) throws Exception
|
||||
{
|
||||
ContextHandlerCollection contexts = app.getDeploymentManager().getContexts();
|
||||
|
||||
ContextHandler handler = app.getContextHandler();
|
||||
|
||||
// start the handler
|
||||
handler.start();
|
||||
|
||||
// After starting let the context manage state
|
||||
app.getDeploymentManager().getContexts().manage(handler);
|
||||
|
||||
if (contexts.isStarted() && handler.isStopped())
|
||||
{
|
||||
// start the handler manually
|
||||
handler.start();
|
||||
|
||||
// After starting let the context manage state
|
||||
contexts.manage(handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,6 @@ import org.eclipse.jetty.plus.jndi.NamingEntryUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.webapp.AbstractConfiguration;
|
||||
import org.eclipse.jetty.webapp.Configuration;
|
||||
import org.eclipse.jetty.webapp.WebAppClassLoader;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.xml.XmlConfiguration;
|
||||
|
@ -548,14 +548,14 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
||||
if (isLogUrlOnStart())
|
||||
dumpUrl();
|
||||
}
|
||||
catch (Exception e)
|
||||
catch (Throwable t)
|
||||
{
|
||||
//start up of the webapp context failed, make sure it is not started
|
||||
LOG.warn("Failed startup of context "+this, e);
|
||||
_unavailableException=e;
|
||||
setAvailable(false);
|
||||
// start up of the webapp context failed, make sure it is not started
|
||||
LOG.warn("Failed startup of context "+this, t);
|
||||
_unavailableException=t;
|
||||
setAvailable(false); // webapp cannot be accessed (results in status code 503)
|
||||
if (isThrowUnavailableOnStartupException())
|
||||
throw e;
|
||||
throw t;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,38 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.test;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.ServletContainerInitializer;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
|
||||
/**
|
||||
* A SCI that tosses an Error to intentionally to cause issues with the DeploymentManager
|
||||
* @see <a href="https://github.com/eclipse/jetty.project/issues/1602">Issue #1602</a>
|
||||
*/
|
||||
public class DeploymentErrorInitializer implements ServletContainerInitializer
|
||||
{
|
||||
@Override
|
||||
public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException
|
||||
{
|
||||
throw new NoClassDefFoundError("Intentional.Failure");
|
||||
}
|
||||
}
|
@ -0,0 +1,407 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.test;
|
||||
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.hamcrest.core.Is.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.deploy.App;
|
||||
import org.eclipse.jetty.deploy.AppLifeCycle;
|
||||
import org.eclipse.jetty.deploy.DeploymentManager;
|
||||
import org.eclipse.jetty.deploy.graph.Node;
|
||||
import org.eclipse.jetty.deploy.providers.WebAppProvider;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.io.RuntimeIOException;
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.ServerConnector;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
|
||||
import org.eclipse.jetty.server.handler.DefaultHandler;
|
||||
import org.eclipse.jetty.server.handler.HandlerCollection;
|
||||
import org.eclipse.jetty.toolchain.test.FS;
|
||||
import org.eclipse.jetty.toolchain.test.IO;
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.eclipse.jetty.util.log.StacklessLogging;
|
||||
import org.eclipse.jetty.util.resource.PathResource;
|
||||
import org.eclipse.jetty.webapp.AbstractConfiguration;
|
||||
import org.eclipse.jetty.webapp.Configuration;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
import org.junit.After;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.junit.rules.TestName;
|
||||
|
||||
public class DeploymentErrorTest
|
||||
{
|
||||
@Rule
|
||||
public ExpectedException expectedException = ExpectedException.none();
|
||||
|
||||
@Rule
|
||||
public TestName testname = new TestName();
|
||||
|
||||
private StacklessLogging stacklessLogging;
|
||||
private Server server;
|
||||
private DeploymentManager deploymentManager;
|
||||
private ContextHandlerCollection contexts;
|
||||
|
||||
public Path startServer(Consumer<Path> docrootSetupConsumer) throws Exception
|
||||
{
|
||||
stacklessLogging = new StacklessLogging(WebAppContext.class, DeploymentManager.class, NoClassDefFoundError.class);
|
||||
|
||||
server = new Server();
|
||||
ServerConnector connector = new ServerConnector(server);
|
||||
connector.setPort(0);
|
||||
server.addConnector(connector);
|
||||
|
||||
// Empty contexts collections
|
||||
contexts = new ContextHandlerCollection();
|
||||
|
||||
// Deployment Manager
|
||||
deploymentManager = new DeploymentManager();
|
||||
deploymentManager.setContexts(contexts);
|
||||
Path testClasses = MavenTestingUtils.getTargetPath("test-classes");
|
||||
System.setProperty("maven.test.classes", testClasses.toAbsolutePath().toString());
|
||||
|
||||
Path docroots = MavenTestingUtils.getTargetTestingPath(DeploymentErrorTest.class, testname.getMethodName());
|
||||
FS.ensureEmpty(docroots);
|
||||
|
||||
if (docrootSetupConsumer != null)
|
||||
{
|
||||
docrootSetupConsumer.accept(docroots);
|
||||
}
|
||||
|
||||
System.setProperty("test.docroots", docroots.toAbsolutePath().toString());
|
||||
WebAppProvider appProvider = new WebAppProvider();
|
||||
appProvider.setMonitoredDirResource(new PathResource(docroots));
|
||||
appProvider.setScanInterval(1);
|
||||
deploymentManager.addAppProvider(appProvider);
|
||||
server.addBean(deploymentManager);
|
||||
|
||||
// Server handlers
|
||||
HandlerCollection handlers = new HandlerCollection();
|
||||
handlers.setHandlers(new Handler[]
|
||||
{contexts, new DefaultHandler()});
|
||||
server.setHandler(handlers);
|
||||
|
||||
// Setup Configurations
|
||||
Configuration.ClassList classlist = Configuration.ClassList
|
||||
.setServerDefault(server);
|
||||
classlist.addAfter(
|
||||
"org.eclipse.jetty.webapp.FragmentConfiguration",
|
||||
"org.eclipse.jetty.plus.webapp.EnvConfiguration",
|
||||
"org.eclipse.jetty.plus.webapp.PlusConfiguration");
|
||||
classlist.addBefore(
|
||||
"org.eclipse.jetty.webapp.JettyWebXmlConfiguration",
|
||||
"org.eclipse.jetty.annotations.AnnotationConfiguration");
|
||||
|
||||
// Tracking Config
|
||||
classlist.addBefore("org.eclipse.jetty.webapp.WebInfConfiguration",
|
||||
TrackedConfiguration.class.getName());
|
||||
|
||||
server.start();
|
||||
return docroots;
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDownServer() throws Exception
|
||||
{
|
||||
if (stacklessLogging != null)
|
||||
stacklessLogging.close();
|
||||
server.stop();
|
||||
}
|
||||
|
||||
private void copyBadApp(String sourceXml, Path docroots)
|
||||
{
|
||||
try
|
||||
{
|
||||
File deployErrorSrc = MavenTestingUtils.getTestResourceDir("docroots/deployerror");
|
||||
IO.copy(new File(deployErrorSrc, sourceXml), docroots.resolve("badapp.xml").toFile());
|
||||
File badappDir = new File(deployErrorSrc, "badapp");
|
||||
File badappDest = docroots.resolve("badapp").toFile();
|
||||
FS.ensureDirExists(badappDest);
|
||||
IO.copyDir(badappDir, badappDest);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new RuntimeIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of a server startup, where a DeploymentManager has a WebAppProvider pointing
|
||||
* to a directory that already has a webapp that will deploy with an error.
|
||||
* The webapp is a WebAppContext with {@code throwUnavailableOnStartupException=true;}.
|
||||
*/
|
||||
@Test
|
||||
public void testInitial_BadApp_UnavailableTrue() throws Exception
|
||||
{
|
||||
expectedException.expect(NoClassDefFoundError.class);
|
||||
startServer(docroots -> copyBadApp("badapp.xml", docroots));
|
||||
|
||||
// The above should have prevented the server from starting.
|
||||
assertThat("server.isRunning", server.isRunning(), is(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of a server startup, where a DeploymentManager has a WebAppProvider pointing
|
||||
* to a directory that already has a webapp that will deploy with an error.
|
||||
* The webapp is a WebAppContext with {@code throwUnavailableOnStartupException=false;}.
|
||||
*/
|
||||
@Test
|
||||
public void testInitial_BadApp_UnavailableFalse() throws Exception
|
||||
{
|
||||
startServer(docroots -> copyBadApp("badapp-unavailable-false.xml", docroots));
|
||||
|
||||
List<App> apps = new ArrayList<>();
|
||||
apps.addAll(deploymentManager.getApps());
|
||||
assertThat("Apps tracked", apps.size(), is(1));
|
||||
String contextPath = "/badapp-uaf";
|
||||
App app = findApp(contextPath, apps);
|
||||
ContextHandler context = app.getContextHandler();
|
||||
assertThat("ContextHandler.isStarted", context.isStarted(), is(true));
|
||||
assertThat("ContextHandler.isFailed", context.isFailed(), is(false));
|
||||
assertThat("ContextHandler.isAvailable", context.isAvailable(), is(false));
|
||||
WebAppContext webapp = (WebAppContext) context;
|
||||
TrackedConfiguration trackedConfiguration = null;
|
||||
for (Configuration webappConfig : webapp.getConfigurations())
|
||||
{
|
||||
if (webappConfig instanceof TrackedConfiguration)
|
||||
trackedConfiguration = (TrackedConfiguration) webappConfig;
|
||||
}
|
||||
assertThat("webapp TrackedConfiguration exists", trackedConfiguration, notNullValue());
|
||||
assertThat("trackedConfig.preConfigureCount", trackedConfiguration.preConfigureCounts.get(contextPath), is(1));
|
||||
assertThat("trackedConfig.configureCount", trackedConfiguration.configureCounts.get(contextPath), is(1));
|
||||
// NOTE: Failure occurs during configure, so postConfigure never runs.
|
||||
assertThat("trackedConfig.postConfigureCount", trackedConfiguration.postConfigureCounts.get(contextPath), nullValue());
|
||||
|
||||
assertHttpState(contextPath, HttpStatus.SERVICE_UNAVAILABLE_503);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of a server startup, where a DeploymentManager has a WebAppProvider pointing
|
||||
* to a directory that already has no initial webapps that will deploy.
|
||||
* A webapp is added (by filesystem copies) into the monitored docroot.
|
||||
* The webapp will have a deployment error.
|
||||
* The webapp is a WebAppContext with {@code throwUnavailableOnStartupException=true;}.
|
||||
*/
|
||||
@Test
|
||||
public void testDelayedAdd_BadApp_UnavailableTrue() throws Exception
|
||||
{
|
||||
Path docroots = startServer(null);
|
||||
|
||||
String contextPath = "/badapp";
|
||||
AppLifeCycleTrackingBinding startTracking = new AppLifeCycleTrackingBinding(contextPath);
|
||||
DeploymentManager deploymentManager = server.getBean(DeploymentManager.class);
|
||||
deploymentManager.addLifeCycleBinding(startTracking);
|
||||
|
||||
copyBadApp("badapp.xml", docroots);
|
||||
|
||||
// Wait for deployment manager to do its thing
|
||||
assertThat("AppLifeCycle.FAILED event occurred", startTracking.failedLatch.await(3, TimeUnit.SECONDS), is(true));
|
||||
|
||||
List<App> apps = new ArrayList<>();
|
||||
apps.addAll(deploymentManager.getApps());
|
||||
assertThat("Apps tracked", apps.size(), is(1));
|
||||
App app = findApp(contextPath, apps);
|
||||
ContextHandler context = app.getContextHandler();
|
||||
assertThat("ContextHandler.isStarted", context.isStarted(), is(false));
|
||||
assertThat("ContextHandler.isFailed", context.isFailed(), is(true));
|
||||
assertThat("ContextHandler.isAvailable", context.isAvailable(), is(false));
|
||||
WebAppContext webapp = (WebAppContext) context;
|
||||
TrackedConfiguration trackedConfiguration = null;
|
||||
for (Configuration webappConfig : webapp.getConfigurations())
|
||||
{
|
||||
if (webappConfig instanceof TrackedConfiguration)
|
||||
trackedConfiguration = (TrackedConfiguration) webappConfig;
|
||||
}
|
||||
assertThat("webapp TrackedConfiguration exists", trackedConfiguration, notNullValue());
|
||||
assertThat("trackedConfig.preConfigureCount", trackedConfiguration.preConfigureCounts.get(contextPath), is(1));
|
||||
assertThat("trackedConfig.configureCount", trackedConfiguration.configureCounts.get(contextPath), is(1));
|
||||
// NOTE: Failure occurs during configure, so postConfigure never runs.
|
||||
assertThat("trackedConfig.postConfigureCount", trackedConfiguration.postConfigureCounts.get(contextPath), nullValue());
|
||||
|
||||
assertHttpState(contextPath, HttpStatus.NOT_FOUND_404);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of a server startup, where a DeploymentManager has a WebAppProvider pointing
|
||||
* to a directory that already has no initial webapps that will deploy.
|
||||
* A webapp is added (by filesystem copies) into the monitored docroot.
|
||||
* The webapp will have a deployment error.
|
||||
* The webapp is a WebAppContext with {@code throwUnavailableOnStartupException=false;}.
|
||||
*/
|
||||
@Test
|
||||
public void testDelayedAdd_BadApp_UnavailableFalse() throws Exception
|
||||
{
|
||||
Path docroots = startServer(null);
|
||||
|
||||
String contextPath = "/badapp-uaf";
|
||||
AppLifeCycleTrackingBinding startTracking = new AppLifeCycleTrackingBinding(contextPath);
|
||||
DeploymentManager deploymentManager = server.getBean(DeploymentManager.class);
|
||||
deploymentManager.addLifeCycleBinding(startTracking);
|
||||
|
||||
copyBadApp("badapp-unavailable-false.xml", docroots);
|
||||
|
||||
// Wait for deployment manager to do its thing
|
||||
startTracking.startedLatch.await(3, TimeUnit.SECONDS);
|
||||
|
||||
List<App> apps = new ArrayList<>();
|
||||
apps.addAll(deploymentManager.getApps());
|
||||
assertThat("Apps tracked", apps.size(), is(1));
|
||||
App app = findApp(contextPath, apps);
|
||||
ContextHandler context = app.getContextHandler();
|
||||
assertThat("ContextHandler.isStarted", context.isStarted(), is(true));
|
||||
assertThat("ContextHandler.isFailed", context.isFailed(), is(false));
|
||||
assertThat("ContextHandler.isAvailable", context.isAvailable(), is(false));
|
||||
WebAppContext webapp = (WebAppContext) context;
|
||||
TrackedConfiguration trackedConfiguration = null;
|
||||
for (Configuration webappConfig : webapp.getConfigurations())
|
||||
{
|
||||
if (webappConfig instanceof TrackedConfiguration)
|
||||
trackedConfiguration = (TrackedConfiguration) webappConfig;
|
||||
}
|
||||
assertThat("webapp TrackedConfiguration exists", trackedConfiguration, notNullValue());
|
||||
assertThat("trackedConfig.preConfigureCount", trackedConfiguration.preConfigureCounts.get(contextPath), is(1));
|
||||
assertThat("trackedConfig.configureCount", trackedConfiguration.configureCounts.get(contextPath), is(1));
|
||||
// NOTE: Failure occurs during configure, so postConfigure never runs.
|
||||
assertThat("trackedConfig.postConfigureCount", trackedConfiguration.postConfigureCounts.get(contextPath), nullValue());
|
||||
|
||||
assertHttpState(contextPath, HttpStatus.SERVICE_UNAVAILABLE_503);
|
||||
}
|
||||
|
||||
private void assertHttpState(String contextPath, int expectedStatusCode) throws Exception
|
||||
{
|
||||
URI destURI = server.getURI().resolve(contextPath);
|
||||
HttpClient client = new HttpClient();
|
||||
try
|
||||
{
|
||||
client.start();
|
||||
ContentResponse response = client.newRequest(destURI).method(HttpMethod.GET).send();
|
||||
assertThat("GET Response: " + destURI, response.getStatus(), is(expectedStatusCode));
|
||||
}
|
||||
finally
|
||||
{
|
||||
client.stop();
|
||||
}
|
||||
}
|
||||
|
||||
private App findApp(String contextPath, List<App> apps)
|
||||
{
|
||||
for (App app : apps)
|
||||
{
|
||||
if (contextPath.equals(app.getContextPath()))
|
||||
return app;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static class TrackedConfiguration extends AbstractConfiguration
|
||||
{
|
||||
public Map<String, Integer> preConfigureCounts = new HashMap<>();
|
||||
public Map<String, Integer> configureCounts = new HashMap<>();
|
||||
public Map<String, Integer> postConfigureCounts = new HashMap<>();
|
||||
|
||||
private void incrementCount(WebAppContext context, Map<String, Integer> contextCounts)
|
||||
{
|
||||
Integer count = contextCounts.get(context.getContextPath());
|
||||
if (count == null)
|
||||
{
|
||||
count = new Integer(0);
|
||||
}
|
||||
count++;
|
||||
contextCounts.put(context.getContextPath(), count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preConfigure(WebAppContext context) throws Exception
|
||||
{
|
||||
incrementCount(context, preConfigureCounts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(WebAppContext context) throws Exception
|
||||
{
|
||||
incrementCount(context, configureCounts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postConfigure(WebAppContext context) throws Exception
|
||||
{
|
||||
incrementCount(context, postConfigureCounts);
|
||||
}
|
||||
}
|
||||
|
||||
public static class AppLifeCycleTrackingBinding implements AppLifeCycle.Binding
|
||||
{
|
||||
public final CountDownLatch startingLatch = new CountDownLatch(1);
|
||||
public final CountDownLatch startedLatch = new CountDownLatch(1);
|
||||
public final CountDownLatch failedLatch = new CountDownLatch(1);
|
||||
private final String expectedContextPath;
|
||||
|
||||
public AppLifeCycleTrackingBinding(String expectedContextPath)
|
||||
{
|
||||
this.expectedContextPath = expectedContextPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getBindingTargets()
|
||||
{
|
||||
return new String[]{AppLifeCycle.STARTING, AppLifeCycle.STARTED, AppLifeCycle.FAILED};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processBinding(Node node, App app)
|
||||
{
|
||||
if (app.getContextPath().equalsIgnoreCase(expectedContextPath))
|
||||
{
|
||||
if (node.getName().equalsIgnoreCase(AppLifeCycle.STARTING))
|
||||
{
|
||||
startingLatch.countDown();
|
||||
}
|
||||
else if (node.getName().equalsIgnoreCase(AppLifeCycle.STARTED))
|
||||
{
|
||||
startedLatch.countDown();
|
||||
}
|
||||
else if (node.getName().equalsIgnoreCase(AppLifeCycle.FAILED))
|
||||
{
|
||||
failedLatch.countDown();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
|
||||
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
|
||||
<Set name="contextPath">/badapp-uaf</Set>
|
||||
<Set name="war"><SystemProperty name="test.docroots"/>/badapp/</Set>
|
||||
<Set name="extraClasspath"><SystemProperty name="maven.test.classes"/></Set>
|
||||
<Set name="throwUnavailableOnStartupException">false</Set> <!-- Intentionally set to false to test behavior -->
|
||||
<Call name="setAttribute">
|
||||
<Arg>org.eclipse.jetty.containerInitializerExclusionPattern</Arg>
|
||||
<Arg>org.jboss.*</Arg>
|
||||
</Call>
|
||||
</Configure>
|
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
|
||||
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
|
||||
<Set name="contextPath">/badapp</Set>
|
||||
<Set name="war"><SystemProperty name="test.docroots"/>/badapp/</Set>
|
||||
<Set name="extraClasspath"><SystemProperty name="maven.test.classes"/></Set>
|
||||
<Set name="throwUnavailableOnStartupException">true</Set>
|
||||
<Call name="setAttribute">
|
||||
<Arg>org.eclipse.jetty.containerInitializerExclusionPattern</Arg>
|
||||
<Arg>org.jboss.*</Arg>
|
||||
</Call>
|
||||
</Configure>
|
@ -0,0 +1 @@
|
||||
org.eclipse.jetty.test.DeploymentErrorInitializer
|
@ -0,0 +1,7 @@
|
||||
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
|
||||
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
|
||||
version="3.1">
|
||||
<display-name>Intentional Deployment Error WebApp</display-name>
|
||||
</web-app>
|
Loading…
x
Reference in New Issue
Block a user