diff --git a/tomcat-managed-10/pom.xml b/tomcat-managed-10/pom.xml
new file mode 100755
index 0000000..6872b61
--- /dev/null
+++ b/tomcat-managed-10/pom.xml
@@ -0,0 +1,51 @@
+
+
+ 4.0.0
+
+ org.jboss.arquillian.container
+ arquillian-tomcat-managed-parent
+ 1.2.1-SNAPSHOT
+ ../tomcat-managed-parent/pom.xml
+
+
+ arquillian-tomcat-managed-10
+ Arquillian Container Tomcat Managed 10.x
+
+
+ 10
+ ${tomcat.major.version}.1.19
+ ${project.build.directory}/cargo/installs/apache-tomcat-${tomcat.version}/apache-tomcat-${tomcat.version}
+ ${project.build.directory}/cargo/configurations/tomcat${tomcat.major.version}x
+
+
+
+
+ javax.servlet
+ javax.servlet-api
+ 3.1.0
+ test
+
+
+
+
+
+
+ org.codehaus.cargo
+ cargo-maven2-plugin
+
+
+ install-container
+
+
+ tomcat${tomcat.major.version}x
+
+ https://archive.apache.org/dist/tomcat/tomcat-${tomcat.major.version}/v${tomcat.version}/bin/apache-tomcat-${tomcat.version}.zip
+
+
+
+
+
+
+
+
+
diff --git a/tomcat-managed-10/src/main/java/org/jboss/arquillian/container/tomcat/managed/Tomcat10ManagedContainer.java b/tomcat-managed-10/src/main/java/org/jboss/arquillian/container/tomcat/managed/Tomcat10ManagedContainer.java
new file mode 100755
index 0000000..7d15392
--- /dev/null
+++ b/tomcat-managed-10/src/main/java/org/jboss/arquillian/container/tomcat/managed/Tomcat10ManagedContainer.java
@@ -0,0 +1,40 @@
+/*
+ * 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.managed;
+
+import org.jboss.arquillian.container.spi.client.container.DeployableContainer;
+import org.jboss.arquillian.container.spi.client.protocol.ProtocolDescription;
+import org.jboss.arquillian.container.tomcat.Tomcat7ManagerCommandSpec;
+
+/**
+ *
+ * Arquillian {@link DeployableContainer} implementation for an Managed Tomcat server; responsible for both lifecycle and
+ * deployment operations.
+ *
+ *
+ * @author Karel Piwko
+ * @author Juraj Huska
+ * @author Ondrej Zizka
+ * @author Dimitrij Drus
+ * @version $Revision: #1 $
+ */
+public class Tomcat10ManagedContainer extends TomcatManagedContainer {
+
+ public Tomcat10ManagedContainer() {
+ super(new ProtocolDescription("Servlet 5.0"), new Tomcat7ManagerCommandSpec());
+ }
+}
diff --git a/tomcat-managed-10/src/main/java/org/jboss/arquillian/container/tomcat/managed/Tomcat10ManagedExtension.java b/tomcat-managed-10/src/main/java/org/jboss/arquillian/container/tomcat/managed/Tomcat10ManagedExtension.java
new file mode 100755
index 0000000..2cbfc91
--- /dev/null
+++ b/tomcat-managed-10/src/main/java/org/jboss/arquillian/container/tomcat/managed/Tomcat10ManagedExtension.java
@@ -0,0 +1,12 @@
+package org.jboss.arquillian.container.tomcat.managed;
+
+import org.jboss.arquillian.container.spi.client.container.DeployableContainer;
+import org.jboss.arquillian.core.spi.LoadableExtension;
+
+public class Tomcat10ManagedExtension implements LoadableExtension {
+
+ @Override
+ public void register(final ExtensionBuilder builder) {
+ builder.service(DeployableContainer.class, Tomcat10ManagedContainer.class);
+ }
+}
diff --git a/tomcat-managed-10/src/main/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension b/tomcat-managed-10/src/main/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension
new file mode 100755
index 0000000..48c77b3
--- /dev/null
+++ b/tomcat-managed-10/src/main/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension
@@ -0,0 +1 @@
+org.jboss.arquillian.container.tomcat.managed.Tomcat10ManagedExtension
diff --git a/tomcat-managed-10/src/test/java/org/jboss/arquillian/container/tomcat/managed/Tomcat10ManagedClientIT.java b/tomcat-managed-10/src/test/java/org/jboss/arquillian/container/tomcat/managed/Tomcat10ManagedClientIT.java
new file mode 100755
index 0000000..61c0694
--- /dev/null
+++ b/tomcat-managed-10/src/test/java/org/jboss/arquillian/container/tomcat/managed/Tomcat10ManagedClientIT.java
@@ -0,0 +1,51 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2014, 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.managed;
+
+import static org.jboss.arquillian.container.tomcat.test.TestDeploymentFactory.ROOT_CONTEXT;
+import static org.jboss.arquillian.container.tomcat.test.TestDeploymentFactory.SERVLET_5;
+import static org.jboss.arquillian.container.tomcat.test.TestDeploymentFactory.TEST_CONTEXT;
+
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.container.tomcat.test.TomcatClientITBase;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests that Tomcat deployments into the Tomcat 8 server work through the Arquillian lifecycle
+ *
+ * @author Jean Deruelle
+ * @author Dan Allen
+ * @author Dimitrij Drus
+ * @version $Revision: $
+ */
+@RunWith(Arquillian.class)
+public class Tomcat10ManagedClientIT extends TomcatClientITBase {
+
+ @Deployment(name = ROOT_CONTEXT, testable = false)
+ public static WebArchive createRootDeployment() {
+
+ return TEST_DEPLOYMENT_FACTORY.createWebAppClientDeployment(ROOT_CONTEXT, SERVLET_5);
+ }
+
+ @Deployment(name = TEST_CONTEXT, testable = false)
+ public static WebArchive createTestDeployment() {
+
+ return TEST_DEPLOYMENT_FACTORY.createWebAppClientDeployment(TEST_CONTEXT, SERVLET_5);
+ }
+}
diff --git a/tomcat-managed-10/src/test/java/org/jboss/arquillian/container/tomcat/managed/Tomcat10ManagedInContainerIT.java b/tomcat-managed-10/src/test/java/org/jboss/arquillian/container/tomcat/managed/Tomcat10ManagedInContainerIT.java
new file mode 100755
index 0000000..c500139
--- /dev/null
+++ b/tomcat-managed-10/src/test/java/org/jboss/arquillian/container/tomcat/managed/Tomcat10ManagedInContainerIT.java
@@ -0,0 +1,49 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2014, 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.managed;
+
+import static org.jboss.arquillian.container.tomcat.test.TestDeploymentFactory.ROOT_CONTEXT;
+import static org.jboss.arquillian.container.tomcat.test.TestDeploymentFactory.SERVLET_5;
+import static org.jboss.arquillian.container.tomcat.test.TestDeploymentFactory.TEST_CONTEXT;
+
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.container.tomcat.test.TomcatInContainerITBase;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests that Tomcat deployments into the Tomcat 8 server work through the Arquillian lifecycle
+ *
+ * @author Dimitrij Drus
+ * @version $Revision: $
+ */
+@RunWith(Arquillian.class)
+public class Tomcat10ManagedInContainerIT extends TomcatInContainerITBase {
+
+ @Deployment(name = ROOT_CONTEXT)
+ public static WebArchive createRootDeployment() {
+
+ return TEST_DEPLOYMENT_FACTORY.createWebAppInContainerDeployment(ROOT_CONTEXT, SERVLET_5);
+ }
+
+ @Deployment(name = TEST_CONTEXT)
+ public static WebArchive createTestDeployment() {
+
+ return TEST_DEPLOYMENT_FACTORY.createWebAppInContainerDeployment(TEST_CONTEXT, SERVLET_5);
+ }
+}
diff --git a/tomcat-managed-10/src/test/resources/arquillian.xml b/tomcat-managed-10/src/test/resources/arquillian.xml
new file mode 100755
index 0000000..5da1d05
--- /dev/null
+++ b/tomcat-managed-10/src/test/resources/arquillian.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+ ${test.catalina.home}
+ ${test.catalina.base}
+ -Xmx1024m
+ ${test.jmx.port}
+ ${test.http.port}
+ server.xml
+ ${test.manager.username}
+ ${test.manager.password}
+
+
+
+
diff --git a/tomcat-managed-10/src/test/resources/tomcat-users.xml b/tomcat-managed-10/src/test/resources/tomcat-users.xml
new file mode 100755
index 0000000..7918383
--- /dev/null
+++ b/tomcat-managed-10/src/test/resources/tomcat-users.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/tomcat-managed-common/pom.xml b/tomcat-managed-common/pom.xml
new file mode 100644
index 0000000..5bdad2b
--- /dev/null
+++ b/tomcat-managed-common/pom.xml
@@ -0,0 +1,53 @@
+
+
+
+ 4.0.0
+
+
+ org.jboss.arquillian.container
+ arquillian-parent-tomcat
+ 1.2.1-SNAPSHOT
+
+
+ arquillian-tomcat-managed-common
+ Arquillian Tomcat Managed Container Common
+
+
+
+
+
+
+ org.jboss.arquillian.container
+ arquillian-tomcat-common
+ ${project.version}
+
+
+
+
+
+ org.jboss.arquillian.container
+ arquillian-tomcat-common
+ ${project.version}
+ test-jar
+ test
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+
+
+
+ test-jar
+
+
+
+
+
+
+
+
diff --git a/tomcat-managed-common/src/main/java/org/jboss/arquillian/container/tomcat/managed/TomcatManagedConfiguration.java b/tomcat-managed-common/src/main/java/org/jboss/arquillian/container/tomcat/managed/TomcatManagedConfiguration.java
new file mode 100644
index 0000000..5b8a407
--- /dev/null
+++ b/tomcat-managed-common/src/main/java/org/jboss/arquillian/container/tomcat/managed/TomcatManagedConfiguration.java
@@ -0,0 +1,225 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2014, 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.managed;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import org.jboss.arquillian.container.spi.ConfigurationException;
+import org.jboss.arquillian.container.tomcat.TomcatConfiguration;
+import org.jboss.arquillian.container.tomcat.Validate;
+
+/**
+ * Arquillian Tomcat Container Configuration
+ *
+ * @author Karel Piwko
+ * @author Juraj Huska
+ * @author Stephen Coy
+ * @version $Revision: $
+ */
+public class TomcatManagedConfiguration extends TomcatConfiguration {
+
+ static final String JAVA_HOME_ENV_PROPERTY = "JAVA_HOME";
+
+ static final String JAVA_HOME_SYSTEM_PROPERTY = "java.home";
+
+ private boolean outputToConsole = true;
+
+ private String catalinaHome = System.getenv("CATALINA_HOME");
+
+ private String catalinaBase = System.getenv("CATALINA_BASE");
+
+ private String javaHome = System.getProperty(JAVA_HOME_ENV_PROPERTY);
+
+ private String javaVmArguments = "-Xmx512m";
+
+ private int startupTimeoutInSeconds = 120;
+
+ private int shutdownTimeoutInSeconds = 45;
+
+ private String workDir = null;
+
+ private String serverConfig = "server.xml";
+
+ private String loggingProperties = "logging.properties";
+
+ public TomcatManagedConfiguration() {
+ // if no javaHome set, reuse this Java JVM
+ if (javaHome == null || "".equals(javaHome)) {
+ javaHome = System.getProperty(JAVA_HOME_SYSTEM_PROPERTY);
+ }
+ }
+
+ @Override
+ public void validate() throws ConfigurationException {
+
+ super.validate();
+
+ Validate.configurationDirectoryExists(catalinaHome,
+ "Either CATALINA_HOME environment variable or catalinaHome property in Arquillian configuration "
+ + "must be set and point to a valid directory! " + catalinaHome + " is not valid directory!");
+
+ Validate.configurationDirectoryExists(javaHome,
+ "Either \"java.home\" system property, JAVA_HOME environment variable or javaHome property in Arquillian configuration "
+ + "must be set and point to a valid directory! " + javaHome + " is not valid directory!");
+
+ //to keep backward compatibility, check catalinaBase only when it's set, otherwise catalinaHome will be used instead
+ if (catalinaBase != null && catalinaBase.length() != 0) {
+ Validate.isValidFile(getCatalinaBase() + "/conf/" + serverConfig,
+ "The server configuration file denoted by serverConfig property has to exist! This file: "
+ + getCatalinaBase()
+ + "/conf/"
+ + serverConfig
+ + " does not!");
+ }
+
+ // set write output to console
+ this.setOutputToConsole(AccessController.doPrivileged(new PrivilegedAction() {
+
+ @Override
+ public Boolean run() {
+
+ // By default, redirect to stdout unless disabled by this property
+ final String val = System.getProperty("org.apache.tomcat.writeconsole");
+ return val == null || !"false".equals(val);
+ }
+ }));
+ }
+
+ public String getCatalinaHome() {
+
+ return catalinaHome;
+ }
+
+ public void setCatalinaHome(final String catalinaHome) {
+
+ this.catalinaHome = catalinaHome;
+ }
+
+ public String getCatalinaBase() {
+ return catalinaBase;
+ }
+
+ public void setCatalinaBase(final String catalinaBase) {
+
+ this.catalinaBase = catalinaBase;
+ }
+
+ public String getJavaHome() {
+
+ return javaHome;
+ }
+
+ public void setJavaHome(final String javaHome) {
+
+ this.javaHome = javaHome;
+ }
+
+ public String getJavaVmArguments() {
+
+ return javaVmArguments;
+ }
+
+ /**
+ * This will override the default ("-Xmx512m") startup JVM arguments.
+ *
+ * @param javaVmArguments
+ * use as start up arguments
+ */
+ public void setJavaVmArguments(final String javaVmArguments) {
+
+ this.javaVmArguments = javaVmArguments;
+ }
+
+ public int getStartupTimeoutInSeconds() {
+
+ return startupTimeoutInSeconds;
+ }
+
+ public void setStartupTimeoutInSeconds(final int startupTimeoutInSeconds) {
+
+ this.startupTimeoutInSeconds = startupTimeoutInSeconds;
+ }
+
+ public int getShutdownTimeoutInSeconds() {
+
+ return shutdownTimeoutInSeconds;
+ }
+
+ public void setShutdownTimeoutInSeconds(final int shutdownTimeoutInSeconds) {
+
+ this.shutdownTimeoutInSeconds = shutdownTimeoutInSeconds;
+ }
+
+ public String getWorkDir() {
+
+ return workDir;
+ }
+
+ /**
+ * @param workDir
+ * the directory where the compiled JSP files and session serialization data is stored
+ */
+ public void setWorkDir(final String workDir) {
+
+ this.workDir = workDir;
+ }
+
+ public String getServerConfig() {
+
+ return serverConfig;
+ }
+
+ public void setServerConfig(final String serverConfig) {
+
+ this.serverConfig = serverConfig;
+ }
+
+ /**
+ * @return the loggingProperties
+ */
+ public String getLoggingProperties() {
+
+ return loggingProperties;
+ }
+
+ /**
+ * @param loggingProperties
+ * the loggingProperties to set
+ */
+ public void setLoggingProperties(final String loggingProperties) {
+
+ this.loggingProperties = loggingProperties;
+ }
+
+ /**
+ * @param outputToConsole
+ * the outputToConsole to set
+ */
+ public void setOutputToConsole(final boolean outputToConsole) {
+
+ this.outputToConsole = outputToConsole;
+ }
+
+ /**
+ * @return the outputToConsole
+ */
+ public boolean isOutputToConsole() {
+
+ return outputToConsole;
+ }
+}
diff --git a/tomcat-managed-common/src/main/java/org/jboss/arquillian/container/tomcat/managed/TomcatManagedContainer.java b/tomcat-managed-common/src/main/java/org/jboss/arquillian/container/tomcat/managed/TomcatManagedContainer.java
new file mode 100644
index 0000000..40cc851
--- /dev/null
+++ b/tomcat-managed-common/src/main/java/org/jboss/arquillian/container/tomcat/managed/TomcatManagedContainer.java
@@ -0,0 +1,326 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2014, 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.managed;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeoutException;
+import java.util.logging.Logger;
+
+import org.jboss.arquillian.container.spi.client.container.DeployableContainer;
+import org.jboss.arquillian.container.spi.client.container.DeploymentException;
+import org.jboss.arquillian.container.spi.client.container.LifecycleException;
+import org.jboss.arquillian.container.spi.client.protocol.ProtocolDescription;
+import org.jboss.arquillian.container.spi.client.protocol.metadata.ProtocolMetaData;
+import org.jboss.arquillian.container.tomcat.AdditionalJavaOptionsParser;
+import org.jboss.arquillian.container.tomcat.ProtocolMetadataParser;
+import org.jboss.arquillian.container.tomcat.ShrinkWrapUtil;
+import org.jboss.arquillian.container.tomcat.TomcatManager;
+import org.jboss.arquillian.container.tomcat.TomcatManagerCommandSpec;
+import org.jboss.arquillian.container.tomcat.Validate;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.descriptor.api.Descriptor;
+
+/**
+ *
+ * Arquillian {@link org.jboss.arquillian.container.spi.client.container.DeployableContainer} implementation for an
+ * Managed
+ * Tomcat server; responsible for both lifecycle and deployment operations.
+ *
+ *
+ * @author Karel Piwko
+ * @author Juraj Huska
+ * @author Ondrej Zizka
+ * @author Stephen Coy
+ * @version $Revision: $
+ */
+abstract class TomcatManagedContainer implements DeployableContainer {
+
+ private static final Logger log = Logger.getLogger(TomcatManagedContainer.class.getName());
+
+ private final TomcatManagerCommandSpec tomcatManagerCommandSpec;
+
+ private final ProtocolDescription protocolDescription;
+
+ /**
+ * Tomcat container configuration
+ */
+ private TomcatManagedConfiguration configuration;
+
+ private TomcatManager extends TomcatManagedConfiguration> manager;
+
+ private Thread shutdownThread;
+
+ private Process startupProcess;
+
+ TomcatManagedContainer(final ProtocolDescription protocolDescription,
+ final TomcatManagerCommandSpec tomcatManagerCommandSpec) {
+
+ this.protocolDescription = protocolDescription;
+ this.tomcatManagerCommandSpec = tomcatManagerCommandSpec;
+ }
+
+ @Override
+ public Class getConfigurationClass() {
+
+ return TomcatManagedConfiguration.class;
+ }
+
+ @Override
+ public ProtocolDescription getDefaultProtocol() {
+
+ return protocolDescription;
+ }
+
+ @Override
+ public void setup(final TomcatManagedConfiguration configuration) {
+
+ this.configuration = configuration;
+ this.manager = new TomcatManager(configuration, tomcatManagerCommandSpec);
+ }
+
+ @Override
+ public void start() throws LifecycleException {
+
+ if (manager.isRunning()) {
+ throw new LifecycleException("The server is already running! "
+ + "Managed containers does not support connecting to running server instances due to the "
+ + "possible harmful effect of connecting to the wrong server. Please stop server before running or "
+ + "change to another type of container.\n"
+ + "To disable this check and allow Arquillian to connect to a running server, "
+ + "set allowConnectingToRunningServer to true in the container configuration");
+ }
+
+ try {
+ final String CATALINA_HOME = configuration.getCatalinaHome();
+ String CATALINA_BASE = configuration.getCatalinaBase();
+ final String ADDITIONAL_JAVA_OPTS = configuration.getJavaVmArguments();
+
+ if (CATALINA_BASE == null) {
+ CATALINA_BASE = CATALINA_HOME;
+ }
+
+ final String absoluteCatalinaHomePath = new File(CATALINA_HOME).getAbsolutePath();
+ final String absoluteCatalinaBasePath = new File(CATALINA_BASE).getAbsolutePath();
+
+ final String javaCommand = getJavaCommand();
+
+ // construct a command to execute
+ final List cmd = new ArrayList();
+
+ cmd.add(javaCommand);
+ String seperator = File.separator;
+
+ cmd.add("-Djava.util.logging.config.file=" + absoluteCatalinaBasePath + seperator + "conf" + seperator
+ + configuration.getLoggingProperties());
+ cmd.add("-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager");
+
+ cmd.add("-Dcom.sun.management.jmxremote.port=" + configuration.getJmxPort());
+ cmd.add("-Dcom.sun.management.jmxremote.ssl=false");
+ cmd.add("-Dcom.sun.management.jmxremote.authenticate=false");
+
+ cmd.addAll(AdditionalJavaOptionsParser.parse(ADDITIONAL_JAVA_OPTS));
+
+ String CLASS_PATH =
+ absoluteCatalinaHomePath + seperator + "bin" + seperator + "bootstrap.jar" + File.pathSeparator;
+ CLASS_PATH += absoluteCatalinaHomePath + seperator + "bin" + seperator + "tomcat-juli.jar";
+
+ cmd.add("-classpath");
+ cmd.add(CLASS_PATH);
+ final File endorsed = new File(absoluteCatalinaHomePath + seperator + "endorsed");
+ if (endorsed.exists()) {
+ cmd.add("-Djava.endorsed.dirs=" + endorsed.getAbsolutePath());
+ }
+ cmd.add("-Dcatalina.base=" + absoluteCatalinaBasePath);
+ cmd.add("-Dcatalina.home=" + absoluteCatalinaHomePath);
+ cmd.add("-Djava.io.tmpdir=" + absoluteCatalinaBasePath + seperator + "temp");
+ cmd.add("org.apache.catalina.startup.Bootstrap");
+ cmd.add("-config");
+ cmd.add(absoluteCatalinaBasePath + seperator + "conf" + seperator + configuration.getServerConfig());
+ cmd.add("start");
+
+ // execute command
+ final ProcessBuilder startupProcessBuilder = new ProcessBuilder(cmd);
+ startupProcessBuilder.redirectErrorStream(true);
+ startupProcessBuilder.directory(new File(configuration.getCatalinaHome() + "/bin"));
+ log.info("Starting Tomcat with: " + cmd.toString());
+ startupProcess = startupProcessBuilder.start();
+ new Thread(new ConsoleConsumer(configuration.isOutputToConsole())).start();
+ final Process proc = startupProcess;
+
+ shutdownThread = new Thread(new Runnable() {
+
+ @Override
+ public void run() {
+
+ if (proc != null) {
+ proc.destroy();
+ try {
+ proc.waitFor();
+ } catch (final InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ });
+ Runtime.getRuntime().addShutdownHook(shutdownThread);
+
+ final long startupTimeout = configuration.getStartupTimeoutInSeconds();
+ long timeout = startupTimeout * 1000;
+ boolean serverAvailable = false;
+ while (timeout > 0 && serverAvailable == false) {
+ serverAvailable = manager.isRunning();
+ if (!serverAvailable) {
+ Thread.sleep(100);
+ timeout -= 100;
+ }
+ }
+ if (!serverAvailable) {
+ destroystartupProcess();
+ throw new TimeoutException(String.format("Managed server was not started within [%d] s", startupTimeout));
+ }
+ } catch (final Exception ex) {
+
+ throw new LifecycleException("Could not start container", ex);
+ }
+ }
+
+ @Override
+ public void stop() throws LifecycleException {
+
+ if (shutdownThread != null) {
+ Runtime.getRuntime().removeShutdownHook(shutdownThread);
+ shutdownThread = null;
+ }
+ try {
+ if (startupProcess != null) {
+ startupProcess.destroy();
+ startupProcess.waitFor();
+ startupProcess = null;
+ }
+ } catch (final Exception e) {
+ throw new LifecycleException("Could not stop container", e);
+ }
+ }
+
+ /**
+ * Deploys to remote Tomcat using it's /manager web-app's org.apache.catalina.manager.ManagerServlet.
+ *
+ * @throws org.jboss.arquillian.container.spi.client.container.DeploymentException
+ */
+ @Override
+ public ProtocolMetaData deploy(final Archive> archive) throws DeploymentException {
+
+ Validate.notNull(archive, "Archive must not be null");
+
+ final String archiveName = manager.normalizeArchiveName(archive.getName());
+ final URL archiveURL = ShrinkWrapUtil.toURL(archive);
+ try {
+ manager.deploy("/" + archiveName, archiveURL);
+ } catch (final IOException e) {
+ throw new DeploymentException("Unable to deploy an archive " + archive.getName(), e);
+ }
+
+ final ProtocolMetadataParser parser =
+ new ProtocolMetadataParser(configuration);
+ return parser.retrieveContextServletInfo(archiveName);
+ }
+
+ @Override
+ public void undeploy(final Archive> archive) throws DeploymentException {
+
+ Validate.notNull(archive, "Archive must not be null");
+
+ final String archiveName = manager.normalizeArchiveName(archive.getName());
+ try {
+ manager.undeploy("/" + archiveName);
+ } catch (final IOException e) {
+ throw new DeploymentException("Unable to undeploy an archive " + archive.getName(), e);
+ }
+ }
+
+ @Override
+ public void deploy(final Descriptor descriptor) throws DeploymentException {
+
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
+ @Override
+ public void undeploy(final Descriptor descriptor) throws DeploymentException {
+
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
+ /**
+ * Runnable that consumes the output of the startupProcess. If nothing consumes the output the AS will hang on some
+ * platforms
+ *
+ * @author Stuart Douglas
+ */
+ private class ConsoleConsumer implements Runnable {
+
+ private final boolean writeOutput;
+
+ ConsoleConsumer(final boolean writeOutput) {
+
+ this.writeOutput = writeOutput;
+ }
+
+ @Override
+ public void run() {
+
+ final InputStream stream = startupProcess.getInputStream();
+ final BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
+ String line = null;
+ try {
+ while ((line = reader.readLine()) != null) {
+ if (writeOutput) {
+ System.out.println(line);
+ }
+ }
+ } catch (final IOException e) {
+ }
+ }
+ }
+
+ private int destroystartupProcess() {
+
+ if (startupProcess == null)
+ return 0;
+ startupProcess.destroy();
+ try {
+ return startupProcess.waitFor();
+ } catch (final InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ String getJavaCommand() {
+
+ if (configuration == null) {
+ throw new IllegalStateException("setup not called");
+ }
+
+ return configuration.getJavaHome() + File.separator + "bin" + File.separator + "java";
+ }
+}
diff --git a/tomcat-managed-common/src/test/java/org/jboss/arquillian/container/tomcat/managed/TomcatManagedConfigurationTest.java b/tomcat-managed-common/src/test/java/org/jboss/arquillian/container/tomcat/managed/TomcatManagedConfigurationTest.java
new file mode 100644
index 0000000..ade1f7c
--- /dev/null
+++ b/tomcat-managed-common/src/test/java/org/jboss/arquillian/container/tomcat/managed/TomcatManagedConfigurationTest.java
@@ -0,0 +1,34 @@
+package org.jboss.arquillian.container.tomcat.managed;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+public class TomcatManagedConfigurationTest {
+
+ @Test
+ public void testGetJavaHomeForDefault() {
+
+ final TomcatManagedConfiguration commonTomcatManagedConfiguration = new TomcatManagedConfiguration();
+
+ final String expectedJavaHome = System.getProperty(TomcatManagedConfiguration.JAVA_HOME_SYSTEM_PROPERTY);
+
+ final String actualJavaHome = commonTomcatManagedConfiguration.getJavaHome();
+
+ assertEquals(expectedJavaHome, actualJavaHome);
+ }
+
+ @Test
+ public void testGetJavaHomeForNonDefault() {
+
+ final TomcatManagedConfiguration commonTomcatManagedConfiguration = new TomcatManagedConfiguration();
+
+ final String expectedJavaHome = "EXPECTED_JAVA_HOME";
+
+ commonTomcatManagedConfiguration.setJavaHome(expectedJavaHome);
+
+ final String actualJavaHome = commonTomcatManagedConfiguration.getJavaHome();
+
+ assertEquals(expectedJavaHome, actualJavaHome);
+ }
+}
diff --git a/tomcat-managed-common/src/test/java/org/jboss/arquillian/container/tomcat/managed/TomcatManagedContainerTest.java b/tomcat-managed-common/src/test/java/org/jboss/arquillian/container/tomcat/managed/TomcatManagedContainerTest.java
new file mode 100644
index 0000000..7e962ca
--- /dev/null
+++ b/tomcat-managed-common/src/test/java/org/jboss/arquillian/container/tomcat/managed/TomcatManagedContainerTest.java
@@ -0,0 +1,55 @@
+package org.jboss.arquillian.container.tomcat.managed;
+
+import static org.junit.Assert.*;
+
+import java.io.File;
+
+import org.jboss.arquillian.container.spi.client.protocol.ProtocolDescription;
+import org.jboss.arquillian.container.tomcat.Tomcat7ManagerCommandSpec;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TomcatManagedContainerTest {
+
+ private TomcatManagedContainer commonTomcatManagedContainer;
+
+ @Before
+ public void setUp() {
+
+ commonTomcatManagedContainer =
+ new TomcatManagedContainer(new ProtocolDescription("Servlet 5.0"), new Tomcat7ManagerCommandSpec()) {
+
+ @Override
+ public ProtocolDescription getDefaultProtocol() {
+
+ return null;
+ }
+ };
+ }
+
+ @Test
+ public void testGetJavaCommandForConfiguration() {
+
+ final TomcatManagedConfiguration commonTomcatManagedConfiguration = new TomcatManagedConfiguration();
+
+ final String testJavaHome = File.separator + "test" + File.separator + "java" + File.separator + "home";
+
+ commonTomcatManagedConfiguration.setJavaHome(testJavaHome);
+
+ commonTomcatManagedContainer.setup(commonTomcatManagedConfiguration);
+
+ final String actualJavaCommand = commonTomcatManagedContainer.getJavaCommand();
+
+ final String expectedJavaCommand = testJavaHome + File.separator + "bin" + File.separator + "java";
+
+ assertEquals(expectedJavaCommand, actualJavaCommand);
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testGetJavaCommandForNoConfiguration() {
+
+ // No .setup(commonTomcatManagedConfiguration)
+
+ commonTomcatManagedContainer.getJavaCommand();
+ }
+}
diff --git a/tomcat-managed-parent/pom.xml b/tomcat-managed-parent/pom.xml
new file mode 100644
index 0000000..8928df8
--- /dev/null
+++ b/tomcat-managed-parent/pom.xml
@@ -0,0 +1,74 @@
+
+
+
+ 4.0.0
+
+
+ org.jboss.arquillian.container
+ arquillian-tomcat-container-parent
+ 1.2.1-SNAPSHOT
+ ../tomcat-container-parent/pom.xml
+
+
+ arquillian-tomcat-managed-parent
+ pom
+ Arquillian Tomcat Managed Container Parent
+
+
+
+
+
+
+ org.jboss.arquillian.container
+ arquillian-tomcat-managed-common
+ ${project.version}
+
+
+
+
+
+ org.jboss.arquillian.container
+ arquillian-tomcat-managed-common
+ ${project.version}
+ test-jar
+ test
+
+
+
+
+
+
+
+
+ org.codehaus.cargo
+ cargo-maven2-plugin
+
+
+ install-container
+ pre-integration-test
+
+ configure
+
+
+
+
+ ${test.http.port}
+ ${test.ajp.port}
+ ${test.rmi.port}
+
+
+
+ ${project.build.testOutputDirectory}/tomcat-users.xml
+ conf
+
+
+
+
+
+
+
+
+
+
+
+