[jboss-svn-commits] JBoss Common SVN: r4718 - in arquillian/trunk/containers/tomcat-embedded-6/src: main/java/org/jboss/arquillian/container/tomcat/embedded_6 and 1 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Sun Jul 11 03:27:38 EDT 2010
Author: dan.j.allen
Date: 2010-07-11 03:27:38 -0400 (Sun, 11 Jul 2010)
New Revision: 4718
Added:
arquillian/trunk/containers/tomcat-embedded-6/src/main/java/org/jboss/arquillian/container/tomcat/embedded_6/EmbeddedContextConfig.java
Removed:
arquillian/trunk/containers/tomcat-embedded-6/src/main/java/org/apache/
Modified:
arquillian/trunk/containers/tomcat-embedded-6/src/main/java/org/jboss/arquillian/container/tomcat/embedded_6/TomcatConfiguration.java
arquillian/trunk/containers/tomcat-embedded-6/src/main/java/org/jboss/arquillian/container/tomcat/embedded_6/TomcatContainer.java
arquillian/trunk/containers/tomcat-embedded-6/src/test/resources/arquillian.xml
Log:
ARQ-189 switch to assuming context path begins with /
use temporary directory for tomcat home if not set
optimize container bootstrap
clean out unpacked WAR on undeploy
switch to using a custom, extended ContextConfig
Added: arquillian/trunk/containers/tomcat-embedded-6/src/main/java/org/jboss/arquillian/container/tomcat/embedded_6/EmbeddedContextConfig.java
===================================================================
--- arquillian/trunk/containers/tomcat-embedded-6/src/main/java/org/jboss/arquillian/container/tomcat/embedded_6/EmbeddedContextConfig.java (rev 0)
+++ arquillian/trunk/containers/tomcat-embedded-6/src/main/java/org/jboss/arquillian/container/tomcat/embedded_6/EmbeddedContextConfig.java 2010-07-11 07:27:38 UTC (rev 4718)
@@ -0,0 +1,121 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * 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 org.jboss.arquillian.container.tomcat.embedded_6;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import javax.servlet.ServletContext;
+import org.apache.catalina.startup.Constants;
+import org.apache.catalina.startup.ContextConfig;
+import org.xml.sax.InputSource;
+
+/**
+ * A custom {@link ContextConfig} for use in the Embedded Tomcat
+ * container integration for Arquillian.
+ *
+ * <p>This configuration adds processing of the META-INF/context.xml
+ * descriptor in the web application root when the context is started.
+ * This implementation also marks an unpacked WAR for deletion when
+ * the context is stopped.</p>
+ *
+ * @author Dan Allen
+ */
+public class EmbeddedContextConfig extends ContextConfig
+{
+ /**
+ * Override as a hook to process the application context configuration.
+ */
+ @Override
+ protected void defaultWebConfig()
+ {
+ applicationContextConfig();
+ super.defaultWebConfig();
+ }
+
+ /**
+ * Process the META-INF/context.xml descriptor in the web application root.
+ * This descriptor is not processed when a webapp is added programmatically through a StandardContext
+ */
+ protected void applicationContextConfig()
+ {
+ ServletContext servletContext = context.getServletContext();
+ InputStream stream = servletContext.getResourceAsStream("/" + Constants.ApplicationContextXml);
+ if (stream == null)
+ {
+ return;
+ }
+ // this bad-practice synchronization is inherited
+ synchronized (contextDigester)
+ {
+ URL url = null;
+ try
+ {
+ url = servletContext.getResource("/" + Constants.ApplicationContextXml);
+ }
+ catch (MalformedURLException e)
+ {
+ throw new AssertionError("/" + Constants.ApplicationContextXml + " should not be considered a malformed URL");
+ }
+ InputSource is = new InputSource(url.toExternalForm());
+ is.setByteStream(stream);
+ contextDigester.push(context);
+ try
+ {
+ contextDigester.parse(is);
+ }
+ catch (Exception e)
+ {
+ ok = false;
+ log.error("Parse error in context.xml for " + context.getName(), e);
+ }
+ finally
+ {
+ contextDigester.reset();
+ try
+ {
+ if (stream != null)
+ {
+ stream.close();
+ }
+ }
+ catch (IOException e)
+ {
+ log.error("Error closing context.xml for " + context.getName(), e);
+ }
+ }
+ }
+ log.debug("Done processing " + Constants.ApplicationContextXml + " descriptor");
+ }
+
+ /**
+ * Overridde to assign an internal field that will trigger the removal
+ * of the unpacked WAR when the context is closed.
+ */
+ @Override
+ protected void fixDocBase() throws IOException
+ {
+ super.fixDocBase();
+ // If this field is not null, the unpacked WAR is removed when
+ // the context is closed. This is normally used by the antiLocking
+ // feature, though it should have been the normal behavior, at
+ // least for an embedded container.
+ originalDocBase = context.getDocBase();
+ }
+
+}
Modified: arquillian/trunk/containers/tomcat-embedded-6/src/main/java/org/jboss/arquillian/container/tomcat/embedded_6/TomcatConfiguration.java
===================================================================
--- arquillian/trunk/containers/tomcat-embedded-6/src/main/java/org/jboss/arquillian/container/tomcat/embedded_6/TomcatConfiguration.java 2010-07-11 07:24:24 UTC (rev 4717)
+++ arquillian/trunk/containers/tomcat-embedded-6/src/main/java/org/jboss/arquillian/container/tomcat/embedded_6/TomcatConfiguration.java 2010-07-11 07:27:38 UTC (rev 4718)
@@ -38,9 +38,9 @@
private String workDir = null;
- private String serverName = "tomcat";
+ private String serverName = "arquillian-tomcat-embedded-6";
- private boolean unpackArchive = true;
+ private boolean unpackArchive = false;
public ContainerProfile getContainerProfile()
{
Modified: arquillian/trunk/containers/tomcat-embedded-6/src/main/java/org/jboss/arquillian/container/tomcat/embedded_6/TomcatContainer.java
===================================================================
--- arquillian/trunk/containers/tomcat-embedded-6/src/main/java/org/jboss/arquillian/container/tomcat/embedded_6/TomcatContainer.java 2010-07-11 07:24:24 UTC (rev 4717)
+++ arquillian/trunk/containers/tomcat-embedded-6/src/main/java/org/jboss/arquillian/container/tomcat/embedded_6/TomcatContainer.java 2010-07-11 07:27:38 UTC (rev 4718)
@@ -28,9 +28,13 @@
import org.apache.catalina.Container;
import org.apache.catalina.Engine;
import org.apache.catalina.Host;
+import org.apache.catalina.LifecycleListener;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.core.StandardContext;
+import org.apache.catalina.core.StandardHost;
+import org.apache.catalina.startup.ContextConfig;
import org.apache.catalina.startup.Embedded;
+import org.apache.catalina.startup.ExpandWar;
import org.jboss.arquillian.protocol.servlet_3.ServletMethodExecutor;
import org.jboss.arquillian.spi.Configuration;
import org.jboss.arquillian.spi.ContainerMethodExecutor;
@@ -42,8 +46,15 @@
import org.jboss.shrinkwrap.tomcat.api.ShrinkWrapStandardContext;
/**
- * Arquillian {@link DeployableContainer} adaptor for a target Tomcat
- * environment; responsible for lifecycle and deployment operations
+ * <p>Arquillian {@link DeployableContainer} implementation for an
+ * Embedded Tomcat server; responsible for both lifecycle and deployment
+ * operations.</p>
+ *
+ * <p>Please note that the context path set for the webapp must begin with
+ * a forward slash. Otherwise, certain path operations within Tomcat
+ * will behave inconsistently. Though it goes without saying, the host
+ * name (bindAddress) cannot have a trailing slash for the same
+ * reason.</p>
*
* @author <a href="mailto:jean.deruelle at gmail.com">Jean Deruelle</a>
* @author Dan Allen
@@ -51,14 +62,14 @@
*/
public class TomcatContainer implements DeployableContainer
{
+ private static final Logger log = Logger.getLogger(TomcatContainer.class.getName());
+
private static final String ENV_VAR = "${env.";
private static final String HTTP_PROTOCOL = "http";
- private static final String SEPARATOR = "/";
+ private static final String TMPDIR_SYS_PROP = "java.io.tmpdir";
- private static final Logger log = Logger.getLogger(TomcatContainer.class.getName());
-
/**
* Tomcat embedded
*/
@@ -140,18 +151,19 @@
}
if (embedded == null)
{
- throw new IllegalStateException("start has not been called!");
+ throw new IllegalStateException("Embedded container is not running");
}
try
{
StandardContext standardContext = archive.as(ShrinkWrapStandardContext.class);
- standardContext.setParent(standardHost);
- if (configuration.getTomcatWorkDir() != null)
+ standardContext.addLifecycleListener(new EmbeddedContextConfig());
+ standardContext.setUnpackWAR(configuration.isUnpackArchive());
+ if (standardContext.getUnpackWAR())
{
- standardContext.setWorkDir(configuration.getTomcatWorkDir());
+ deleteUnpackedWAR(standardContext);
}
- standardContext.setUnpackWAR(configuration.isUnpackArchive());
+
standardHost.addChild(standardContext);
context.add(StandardContext.class, standardContext);
}
@@ -181,6 +193,10 @@
if (standardContext != null)
{
standardHost.removeChild(standardContext);
+ if (standardContext.getUnpackWAR())
+ {
+ deleteUnpackedWAR(standardContext);
+ }
}
}
@@ -198,11 +214,9 @@
List<String> remainingDeployments = new ArrayList<String>();
for (String name : failedUndeployments)
{
-
try
{
undeploy(name);
-
}
catch (Exception e)
{
@@ -232,47 +246,52 @@
{
String sysVar = tomcatHome.substring(ENV_VAR.length(), tomcatHome.length() - 1);
tomcatHome = System.getProperty(sysVar);
- tomcatHomeFile = new File(tomcatHome);
- log.info("Using tomcat home from environment variable: " + tomcatHome);
+ if (tomcatHome != null && tomcatHome.length() > 0 && new File(tomcatHome).isAbsolute())
+ {
+ tomcatHomeFile = new File(tomcatHome);
+ log.info("Using tomcat home from environment variable: " + tomcatHome);
+ }
}
- if (tomcatHome != null)
+ else
{
tomcatHomeFile = new File(tomcatHome);
- tomcatHome = tomcatHomeFile.getAbsolutePath();
- embedded.setCatalinaBase(tomcatHome);
- embedded.setCatalinaHome(tomcatHome);
}
- if (tomcatHomeFile != null)
- {
- tomcatHomeFile.mkdirs();
- }
}
- // creates the engine == engine tag in server.xml
+
+ if (tomcatHomeFile == null)
+ {
+ tomcatHomeFile = new File(System.getProperty(TMPDIR_SYS_PROP), "tomcat-embedded-6");
+ }
+
+ tomcatHomeFile.mkdirs();
+ embedded.setCatalinaBase(tomcatHomeFile.getAbsolutePath());
+ embedded.setCatalinaHome(tomcatHomeFile.getAbsolutePath());
+
+ // creates the engine, i.e., <engine> element in server.xml
engine = embedded.createEngine();
engine.setName(serverName);
engine.setDefaultHost(bindAddress);
engine.setService(embedded);
embedded.setContainer(engine);
embedded.addEngine(engine);
- // creates the host == host tag in server.xml
- if (tomcatHomeFile != null)
+
+ // creates the host, i.e., <host> element in server.xml
+ File appBaseFile = new File(tomcatHomeFile, configuration.getAppBase());
+ appBaseFile.mkdirs();
+ standardHost = embedded.createHost(bindAddress, appBaseFile.getAbsolutePath());
+ if (configuration.getTomcatWorkDir() != null)
{
- File appBaseFile = new File(tomcatHomeFile, configuration.getAppBase());
- appBaseFile.mkdirs();
- standardHost = embedded.createHost(bindAddress + SEPARATOR, appBaseFile.getAbsolutePath());
+ ((StandardHost) standardHost).setWorkDir(configuration.getTomcatWorkDir());
}
- else
- {
- standardHost = embedded.createHost(bindAddress + SEPARATOR, System.getProperty("java.io.tmpdir"));
- }
- standardHost.setParent(engine);
+ ((StandardHost) standardHost).setUnpackWARs(configuration.isUnpackArchive());
engine.addChild(standardHost);
- // creates an http connector == connector in server.xml
- // TODO externalize this stuff in the configuration
+
+ // creates an http connector, i.e., <connector> element in server.xml
Connector connector = embedded.createConnector(InetAddress.getByName(bindAddress), bindPort, false);
embedded.addConnector(connector);
connector.setContainer(engine);
- //starts tomcat embedded
+
+ // starts embedded tomcat
embedded.init();
embedded.start();
wasStarted = true;
@@ -282,4 +301,17 @@
{
embedded.stop();
}
+
+ /**
+ * Make sure an the unpacked WAR is not left behind
+ * you would think Tomcat would cleanup an unpacked WAR, but it doesn't
+ */
+ protected void deleteUnpackedWAR(StandardContext standardContext)
+ {
+ File unpackDir = new File(standardHost.getAppBase(), standardContext.getPath().substring(1));
+ if (unpackDir.exists())
+ {
+ ExpandWar.deleteDir(unpackDir);
+ }
+ }
}
Modified: arquillian/trunk/containers/tomcat-embedded-6/src/test/resources/arquillian.xml
===================================================================
--- arquillian/trunk/containers/tomcat-embedded-6/src/test/resources/arquillian.xml 2010-07-11 07:24:24 UTC (rev 4717)
+++ arquillian/trunk/containers/tomcat-embedded-6/src/test/resources/arquillian.xml 2010-07-11 07:27:38 UTC (rev 4718)
@@ -11,12 +11,15 @@
-->
<tomcat6:container>
+ <tomcat6:tomcatHome>target/tomcat-embedded-6</tomcat6:tomcatHome>
+ <!-- other options for setting tomcatHome -->
<!--tomcat6:tomcatHome>/path/to/apache-tomcat-6.0.20</tomcat6:tomcatHome-->
<!--tomcat6:tomcatHome>${env.CATALINA_HOME}</tomcat6:tomcatHome-->
- <tomcat6:tomcatHome>target/tomcat</tomcat6:tomcatHome>
<tomcat6:workDir>work</tomcat6:workDir>
<tomcat6:appBase>webapps</tomcat6:appBase>
<tomcat6:bindHttpPort>8888</tomcat6:bindHttpPort>
+ <!-- unpackArchive must be true if using the Weld Servlet module -->
+ <tomcat6:unpackArchive>true</tomcat6:unpackArchive>
</tomcat6:container>
</arquillian>
More information about the jboss-svn-commits
mailing list