diff --git a/tests/pom.xml b/tests/pom.xml
index b107aa4b07f..4c52947124e 100644
--- a/tests/pom.xml
+++ b/tests/pom.xml
@@ -48,5 +48,6 @@
test-loginservice
test-integration
test-quickstart
+ test-jmx
diff --git a/tests/test-jmx/jmx-webapp-it/pom.xml b/tests/test-jmx/jmx-webapp-it/pom.xml
new file mode 100644
index 00000000000..4272e5072cb
--- /dev/null
+++ b/tests/test-jmx/jmx-webapp-it/pom.xml
@@ -0,0 +1,215 @@
+
+
+
+
+ org.eclipse.jetty.tests
+ test-jmx-parent
+ 9.2.8-SNAPSHOT
+
+ 4.0.0
+ jmx-webapp-it
+ jar
+ Jetty Tests :: JMX :: WebApp Integration Tests
+ http://www.eclipse.org/jetty
+
+ UTF-8
+ UTF-8
+ ${project.groupId}.jmx.webapp.it
+ ${project.basedir}/src/test/scripts
+ ${project.build.directory}/test-base
+ ${project.build.directory}/test-home
+
+
+
+ org.eclipse.jetty
+ jetty-distribution
+ ${project.version}
+ zip
+ runtime
+
+
+ org.eclipse.jetty.tests
+ jmx-webapp
+ ${project.version}
+ war
+ runtime
+
+
+ org.eclipse.jetty.toolchain
+ jetty-test-helper
+ test
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+
+
+ copy-apps-for-testing
+ process-test-resources
+
+ copy-dependencies
+
+
+ jmx-webapp
+ runtime
+ war
+ true
+ true
+ true
+ ${test-base-dir}/webapps
+
+
+
+ unpack-jetty-distro
+ process-test-resources
+
+ unpack-dependencies
+
+
+ jetty-distribution
+ runtime
+ zip
+ true
+ ${test-home-dir}
+ true
+ true
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-failsafe-plugin
+ 2.17
+
+
+
+ integration-test
+ verify
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-antrun-plugin
+ 1.7
+
+
+ start-jetty
+ pre-integration-test
+
+ run
+
+
+
+
+
+ Integration Test : Setup Jetty
+
+
+
+
+
+
+
+
+ Integration Test : Starting Jetty ...
+
+
+
+
+
+
+
+
+
+
+ Integration Test : Jetty is now available
+
+
+
+
+ stop-jetty
+ post-integration-test
+
+ run
+
+
+
+
+
+ Integration Test : Stop Jetty
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ it-windows
+
+
+ Windows
+
+
+
+ cmd
+ /c
+ start-jetty.bat
+ stop-jetty.bat
+
+
+
+ it-unix
+
+
+ unix
+
+
+
+ sh
+ --
+ setup-jetty.sh
+ start-jetty.sh
+ stop-jetty.sh
+
+
+
+
diff --git a/tests/test-jmx/jmx-webapp-it/src/test/java/org/eclipse/jetty/test/jmx/JmxIT.java b/tests/test-jmx/jmx-webapp-it/src/test/java/org/eclipse/jetty/test/jmx/JmxIT.java
new file mode 100644
index 00000000000..aae9618f460
--- /dev/null
+++ b/tests/test-jmx/jmx-webapp-it/src/test/java/org/eclipse/jetty/test/jmx/JmxIT.java
@@ -0,0 +1,144 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2015 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.jmx;
+
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+
+import javax.management.AttributeNotFoundException;
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanException;
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXServiceURL;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Some JMX information tests.
+ */
+public class JmxIT
+{
+ private static JMXConnector jmxc;
+ private static MBeanServerConnection mbsc;
+
+ @BeforeClass
+ public static void connectToMBeanServer() throws IOException
+ {
+ JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://localhost:1099/jndi/rmi://localhost:1099/jmxrmi");
+ jmxc = JMXConnectorFactory.connect(url,null);
+ mbsc = jmxc.getMBeanServerConnection();
+ }
+
+ @AfterClass
+ public static void disconnectFromMBeanServer() throws IOException
+ {
+ jmxc.close();
+ }
+
+ private String getStringAttribute(ObjectName objName, String attrName) throws Exception
+ {
+ Object val = mbsc.getAttribute(objName,attrName);
+ assertThat(attrName,val,notNullValue());
+ assertThat(attrName,val,instanceOf(String.class));
+ return (String)val;
+ }
+
+ private int getIntegerAttribute(ObjectName objName, String attrName) throws Exception
+ {
+ Object val = mbsc.getAttribute(objName,attrName);
+ assertThat(attrName,val,notNullValue());
+ assertThat(attrName,val,instanceOf(Integer.class));
+ return (Integer)val;
+ }
+
+ @Test
+ public void testObtainRunningServerVersion() throws Exception
+ {
+ ObjectName serverName = new ObjectName("org.eclipse.jetty.server:type=server,id=0");
+ String version = getStringAttribute(serverName,"version");
+ System.err.println("Running version: " + version);
+ assertThat("Version",version,startsWith("9.2."));
+ }
+
+ @Test
+ public void testObtainJmxWebAppState() throws Exception
+ {
+ ObjectName webappName = new ObjectName("org.eclipse.jetty.webapp:context=jmx-webapp,type=webappcontext,id=0");
+
+ String contextPath = getStringAttribute(webappName,"contextPath");
+ String displayName = getStringAttribute(webappName,"displayName");
+
+ assertThat("Context Path",contextPath,is("/jmx-webapp"));
+ assertThat("Display Name",displayName,is("Test JMX WebApp"));
+ }
+
+ /**
+ * Test for directly annotated POJOs in the JMX tree
+ */
+ @Test
+ public void testAccessToCommonComponent() throws Exception
+ {
+ ObjectName commonName = new ObjectName("org.eclipse.jetty.test.jmx:type=commoncomponent,context=jmx-webapp,id=0");
+ String name = getStringAttribute(commonName,"name");
+ assertThat("Name",name,is("i am common"));
+ }
+
+ /**
+ * Test for POJO (not annotated) that is supplemented with a MBean that
+ * declares the annotations.
+ */
+ @Test
+ public void testAccessToPingerMBean() throws Exception
+ {
+ ObjectName pingerName = new ObjectName("org.eclipse.jetty.test.jmx:type=pinger,context=jmx-webapp,id=0");
+ // Get initial count
+ int count = getIntegerAttribute(pingerName,"count");
+ // Operations
+ Object val = mbsc.invoke(pingerName,"ping",null,null);
+ assertThat("ping() return",val.toString(),startsWith("Pong"));
+ // Attributes
+ assertThat("count",getIntegerAttribute(pingerName,"count"),is(count+1));
+ }
+
+ /**
+ * Test for POJO (annotated) that is merged with a MBean that
+ * declares more annotations.
+ */
+ @Test
+ public void testAccessToEchoerMBean() throws Exception
+ {
+ ObjectName echoerName = new ObjectName("org.eclipse.jetty.test.jmx:type=echoer,context=jmx-webapp,id=0");
+ // Get initial count
+ int count = getIntegerAttribute(echoerName,"count");
+ // Operations
+ Object val = mbsc.invoke(echoerName,"echo",new Object[]{"Its Me"},new String[]{String.class.getName()});
+ assertThat("echo() return",val.toString(),is("Its Me"));
+ // Attributes
+ assertThat("count",getIntegerAttribute(echoerName,"count"),is(count+1));
+ assertThat("foo",getStringAttribute(echoerName,"foo"),is("foo-ish"));
+ }
+}
diff --git a/tests/test-jmx/jmx-webapp-it/src/test/java/org/eclipse/jetty/test/jmx/PingIT.java b/tests/test-jmx/jmx-webapp-it/src/test/java/org/eclipse/jetty/test/jmx/PingIT.java
new file mode 100644
index 00000000000..f852502b5ec
--- /dev/null
+++ b/tests/test-jmx/jmx-webapp-it/src/test/java/org/eclipse/jetty/test/jmx/PingIT.java
@@ -0,0 +1,41 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2015 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.jmx;
+
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+import java.net.URI;
+
+import org.eclipse.jetty.toolchain.test.SimpleRequest;
+import org.junit.Test;
+
+/**
+ * Basic tests for a simple Servlet with no JMX involved (yet)
+ */
+public class PingIT
+{
+ @Test
+ public void testBasic() throws Exception
+ {
+ URI serverURI = new URI("http://localhost:58080/jmx-webapp/");
+ SimpleRequest req = new SimpleRequest(serverURI);
+ assertThat(req.getString("ping"),startsWith("Servlet Pong at "));
+ }
+}
diff --git a/tests/test-jmx/jmx-webapp-it/src/test/scripts/setup-jetty.sh b/tests/test-jmx/jmx-webapp-it/src/test/scripts/setup-jetty.sh
new file mode 100755
index 00000000000..22beac14dbe
--- /dev/null
+++ b/tests/test-jmx/jmx-webapp-it/src/test/scripts/setup-jetty.sh
@@ -0,0 +1,19 @@
+#!/usr/bin/env bash
+
+JAVA_HOME=$1
+JETTY_HOME=$2
+JETTY_BASE=$3
+
+echo \${java.home} : $JAVA_HOME
+echo \${jetty.home} : $JETTY_HOME
+echo \${jetty.base} : $JETTY_BASE
+
+cd "$JETTY_BASE"
+
+"$JAVA_HOME/bin/java" -jar "$JETTY_HOME/start.jar" \
+ --approve-all-licenses \
+ --add-to-start=deploy,http,annotations,jmx,jmx-remote,logging
+
+"$JAVA_HOME/bin/java" -jar "$JETTY_HOME/start.jar" \
+ --version
+
diff --git a/tests/test-jmx/jmx-webapp-it/src/test/scripts/start-jetty.sh b/tests/test-jmx/jmx-webapp-it/src/test/scripts/start-jetty.sh
new file mode 100755
index 00000000000..1d0f9eb89c7
--- /dev/null
+++ b/tests/test-jmx/jmx-webapp-it/src/test/scripts/start-jetty.sh
@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+
+JAVA_HOME=$1
+JETTY_HOME=$2
+JETTY_BASE=$3
+
+echo \${java.home} : $JAVA_HOME
+echo \${jetty.home} : $JETTY_HOME
+echo \${jetty.base} : $JETTY_BASE
+
+cd "$JETTY_BASE"
+
+"$JAVA_HOME/bin/java" -jar "$JETTY_HOME/start.jar" \
+ jetty.port=58080 \
+ STOP.PORT=58181 STOP.KEY=it
+
+
diff --git a/tests/test-jmx/jmx-webapp-it/src/test/scripts/stop-jetty.sh b/tests/test-jmx/jmx-webapp-it/src/test/scripts/stop-jetty.sh
new file mode 100755
index 00000000000..32e40774908
--- /dev/null
+++ b/tests/test-jmx/jmx-webapp-it/src/test/scripts/stop-jetty.sh
@@ -0,0 +1,11 @@
+#!/usr/bin/env bash
+
+JAVA_HOME=$1
+JETTY_HOME=$2
+JETTY_BASE=$3
+
+cd "$JETTY_BASE"
+"$JAVA_HOME/bin/java" -jar "$JETTY_HOME/start.jar" \
+ --stop STOP.PORT=58181 STOP.KEY=it
+
+
diff --git a/tests/test-jmx/jmx-webapp/pom.xml b/tests/test-jmx/jmx-webapp/pom.xml
new file mode 100644
index 00000000000..3f17c8abc47
--- /dev/null
+++ b/tests/test-jmx/jmx-webapp/pom.xml
@@ -0,0 +1,65 @@
+
+
+
+ 4.0.0
+
+ org.eclipse.jetty.tests
+ test-jmx-parent
+ 9.2.8-SNAPSHOT
+
+ jmx-webapp
+ war
+ Jetty Tests :: JMX :: WebApp
+ http://www.eclipse.org/jetty
+
+ UTF-8
+ ${project.groupId}.jmx.webapp
+
+
+
+ javax.servlet
+ javax.servlet-api
+ provided
+
+
+ org.eclipse.jetty
+ jetty-jmx
+ ${project.version}
+
+
+
+ jmx-webapp
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+
+
+ true
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+
+
+
+
+
+
diff --git a/tests/test-jmx/jmx-webapp/src/main/java/org/eclipse/jetty/test/jmx/CommonComponent.java b/tests/test-jmx/jmx-webapp/src/main/java/org/eclipse/jetty/test/jmx/CommonComponent.java
new file mode 100644
index 00000000000..702e628fad4
--- /dev/null
+++ b/tests/test-jmx/jmx-webapp/src/main/java/org/eclipse/jetty/test/jmx/CommonComponent.java
@@ -0,0 +1,49 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2015 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.jmx;
+
+import org.eclipse.jetty.util.annotation.ManagedAttribute;
+import org.eclipse.jetty.util.annotation.ManagedObject;
+import org.eclipse.jetty.util.component.AbstractLifeCycle;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+@ManagedObject("A common component available in the webapp")
+public class CommonComponent extends AbstractLifeCycle
+{
+ private static final Logger LOG = Log.getLogger(CommonComponent.class);
+
+ public CommonComponent()
+ {
+ LOG.info("Created " + this.getClass().getName());
+ }
+
+ private String name = "i am common";
+
+ @ManagedAttribute("The name being tracked")
+ public String getName()
+ {
+ return name;
+ }
+
+ public void setName(String name)
+ {
+ this.name = name;
+ }
+}
diff --git a/tests/test-jmx/jmx-webapp/src/main/java/org/eclipse/jetty/test/jmx/Echoer.java b/tests/test-jmx/jmx-webapp/src/main/java/org/eclipse/jetty/test/jmx/Echoer.java
new file mode 100644
index 00000000000..f1b13554dbe
--- /dev/null
+++ b/tests/test-jmx/jmx-webapp/src/main/java/org/eclipse/jetty/test/jmx/Echoer.java
@@ -0,0 +1,43 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2015 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.jmx;
+
+import org.eclipse.jetty.util.annotation.ManagedAttribute;
+import org.eclipse.jetty.util.annotation.ManagedObject;
+import org.eclipse.jetty.util.annotation.ManagedOperation;
+import org.eclipse.jetty.util.annotation.Name;
+
+@ManagedObject("Echoer")
+public class Echoer
+{
+ private int count = 0;
+
+ @ManagedAttribute("Number of echos")
+ public int getCount()
+ {
+ return count;
+ }
+
+ @ManagedOperation("Echo a string")
+ public String echo(@Name("val") String val)
+ {
+ count++;
+ return val;
+ }
+}
diff --git a/tests/test-jmx/jmx-webapp/src/main/java/org/eclipse/jetty/test/jmx/MyContainerInitializer.java b/tests/test-jmx/jmx-webapp/src/main/java/org/eclipse/jetty/test/jmx/MyContainerInitializer.java
new file mode 100644
index 00000000000..00f068c632a
--- /dev/null
+++ b/tests/test-jmx/jmx-webapp/src/main/java/org/eclipse/jetty/test/jmx/MyContainerInitializer.java
@@ -0,0 +1,46 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2015 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.jmx;
+
+import java.util.Set;
+
+import javax.servlet.ServletContainerInitializer;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+public class MyContainerInitializer implements ServletContainerInitializer
+{
+ private static final Logger LOG = Log.getLogger(MyContainerInitializer.class);
+
+ @Override
+ public void onStartup(Set> c, ServletContext ctx) throws ServletException
+ {
+ // Directly annotated with @ManagedObject
+ CommonComponent common = new CommonComponent();
+ LOG.info("Initializing " + common.getClass().getName());
+ ctx.setAttribute("org.eclipse.jetty.test.jmx.common",common);
+
+ // Indirectly managed via a MBean
+ ctx.setAttribute("org.eclipse.jetty.test.jmx.ping",new Pinger());
+ ctx.setAttribute("org.eclipse.jetty.test.jmx.echo",new Echoer());
+ }
+}
diff --git a/tests/test-jmx/jmx-webapp/src/main/java/org/eclipse/jetty/test/jmx/PingServlet.java b/tests/test-jmx/jmx-webapp/src/main/java/org/eclipse/jetty/test/jmx/PingServlet.java
new file mode 100644
index 00000000000..4be608a6135
--- /dev/null
+++ b/tests/test-jmx/jmx-webapp/src/main/java/org/eclipse/jetty/test/jmx/PingServlet.java
@@ -0,0 +1,64 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2015 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.jmx;
+
+import java.io.IOException;
+import java.util.Date;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.util.annotation.ManagedObject;
+import org.eclipse.jetty.util.annotation.ManagedOperation;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/**
+ * Simple ping into this webapp to see if it is here.
+ */
+@SuppressWarnings("serial")
+@ManagedObject("Ping Servlet")
+public class PingServlet extends HttpServlet
+{
+ private static final Logger LOG = Log.getLogger(PingServlet.class);
+
+ @Override
+ public void init(ServletConfig config) throws ServletException
+ {
+ LOG.info("Adding {} to attribute {}", this, config.getServletName());
+ config.getServletContext().setAttribute(config.getServletName(),this);
+ super.init(config);
+ }
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
+ {
+ resp.setContentType("text/plain");
+ resp.getWriter().println(ping());
+ }
+
+ @ManagedOperation
+ public String ping()
+ {
+ return "Servlet Pong at " + new Date().toString();
+ }
+}
diff --git a/tests/test-jmx/jmx-webapp/src/main/java/org/eclipse/jetty/test/jmx/Pinger.java b/tests/test-jmx/jmx-webapp/src/main/java/org/eclipse/jetty/test/jmx/Pinger.java
new file mode 100644
index 00000000000..c7845ef6957
--- /dev/null
+++ b/tests/test-jmx/jmx-webapp/src/main/java/org/eclipse/jetty/test/jmx/Pinger.java
@@ -0,0 +1,40 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2015 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.jmx;
+
+import java.util.Date;
+
+/**
+ * Bare POJO, intentionally has no managed annotations.
+ */
+public class Pinger
+{
+ private int count = 0;
+
+ public int getCount()
+ {
+ return count;
+ }
+
+ public String ping()
+ {
+ count++;
+ return "Ponger at " + new Date().toString();
+ }
+}
diff --git a/tests/test-jmx/jmx-webapp/src/main/java/org/eclipse/jetty/test/jmx/jmx/EchoerMBean.java b/tests/test-jmx/jmx-webapp/src/main/java/org/eclipse/jetty/test/jmx/jmx/EchoerMBean.java
new file mode 100644
index 00000000000..97bae5dc28e
--- /dev/null
+++ b/tests/test-jmx/jmx-webapp/src/main/java/org/eclipse/jetty/test/jmx/jmx/EchoerMBean.java
@@ -0,0 +1,38 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2015 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.jmx.jmx;
+
+import org.eclipse.jetty.jmx.ObjectMBean;
+import org.eclipse.jetty.util.annotation.ManagedAttribute;
+import org.eclipse.jetty.util.annotation.ManagedObject;
+
+@ManagedObject("Echoer (mbean)")
+public class EchoerMBean extends ObjectMBean
+{
+ public EchoerMBean(Object managedObject)
+ {
+ super(managedObject);
+ }
+
+ @ManagedAttribute(value="Gets the value of foo",proxied=true)
+ public String getFoo()
+ {
+ return "foo-ish";
+ }
+}
diff --git a/tests/test-jmx/jmx-webapp/src/main/java/org/eclipse/jetty/test/jmx/jmx/PingerMBean.java b/tests/test-jmx/jmx-webapp/src/main/java/org/eclipse/jetty/test/jmx/jmx/PingerMBean.java
new file mode 100644
index 00000000000..f5b65e574f0
--- /dev/null
+++ b/tests/test-jmx/jmx-webapp/src/main/java/org/eclipse/jetty/test/jmx/jmx/PingerMBean.java
@@ -0,0 +1,51 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2015 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.jmx.jmx;
+
+import org.eclipse.jetty.jmx.ObjectMBean;
+import org.eclipse.jetty.test.jmx.Pinger;
+import org.eclipse.jetty.util.annotation.ManagedAttribute;
+import org.eclipse.jetty.util.annotation.ManagedObject;
+import org.eclipse.jetty.util.annotation.ManagedOperation;
+
+@ManagedObject("Pinger facility")
+public class PingerMBean extends ObjectMBean
+{
+ public PingerMBean(Object managedObject)
+ {
+ super(managedObject);
+ }
+
+ private Pinger getPinger()
+ {
+ return (Pinger)getManagedObject();
+ }
+
+ @ManagedOperation("Issue Ping")
+ public String ping()
+ {
+ return getPinger().ping();
+ }
+
+ @ManagedAttribute("Count of pings")
+ public int getCount()
+ {
+ return getPinger().getCount();
+ }
+}
diff --git a/tests/test-jmx/jmx-webapp/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer b/tests/test-jmx/jmx-webapp/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer
new file mode 100644
index 00000000000..2e64dd7d038
--- /dev/null
+++ b/tests/test-jmx/jmx-webapp/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer
@@ -0,0 +1 @@
+org.eclipse.jetty.test.jmx.MyContainerInitializer
\ No newline at end of file
diff --git a/tests/test-jmx/jmx-webapp/src/main/webapp/WEB-INF/web.xml b/tests/test-jmx/jmx-webapp/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 00000000000..68fd25d618c
--- /dev/null
+++ b/tests/test-jmx/jmx-webapp/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,34 @@
+
+
+
+ Test JMX WebApp
+
+
+ org.eclipse.jetty.server.context.ManagedAttributes
+
+ org.eclipse.jetty.test.jmx.common,
+ org.eclipse.jetty.test.jmx.ping,
+ org.eclipse.jetty.test.jmx.echo,
+ Ping
+
+
+
+
+ Ping
+ org.eclipse.jetty.test.jmx.PingServlet
+ 1
+
+
+
+ Ping
+ /ping
+
+
+
+
+
diff --git a/tests/test-jmx/pom.xml b/tests/test-jmx/pom.xml
new file mode 100644
index 00000000000..d43288e167e
--- /dev/null
+++ b/tests/test-jmx/pom.xml
@@ -0,0 +1,34 @@
+
+
+
+
+ org.eclipse.jetty.tests
+ tests-parent
+ 9.2.8-SNAPSHOT
+
+ 4.0.0
+ test-jmx-parent
+ pom
+ Jetty Tests :: JMX Parent
+ http://www.eclipse.org/jetty
+
+ jmx-webapp
+ jmx-webapp-it
+
+