Starting and Stopping Jetty Gracefully with Groovy and JMX
Join the DZone community and get the full member experience.
Join For FreeI'm working on a project that uses Tapestry and ActiveMQ together; it works great on my Mac, but on my client's Windows workstation, ActiveMQ doesn't shut down cleanly and corrupts its local files pretty consistently.
Unfortunately, there isn't a way (using RunJettyRun, the Eclipse plugin for Jetty) to gracefully shutdown Jetty. You just pull the plug on it, mid execution.
Looking for a solution, I realized that Jetty can expose most of its internals via JMX; this would allow us to start it up and shut it down cleanly in development.
So, I created a Groovy LaunchApp class to launch Jetty with JMX enabled:
package com.example.main
import java.lang.management.ManagementFactory
import org.eclipse.jetty.jmx.MBeanContainer
import org.eclipse.jetty.server.Server
import org.eclipse.jetty.webapp.WebAppContext
import org.slf4j.LoggerFactory
/**
* Alternative the RunJettyRun Eclipse plugin that allows greater control over how Jetty starts up.
*/
class LaunchApp {
static PORT = 8080
public static void main(String[] args) {
def LOG = LoggerFactory.getLogger(LaunchApp.class)
LOG.info "Starting up Jetty ${Server.getVersion()} instance on port $PORT ..."
def server = new Server(PORT)
server.stopAtShutdown = true
server.gracefulShutdown = 1000 // 1 second
def context = new WebAppContext()
context.setContextPath "/"
context.setWar "src/main/webapp"
server.setHandler context
def mBeanServer = ManagementFactory.getPlatformMBeanServer();
def mBeanContainer = new MBeanContainer(mBeanServer);
server.container.addEventListener(mBeanContainer);
mBeanContainer.start();
server.start()
LOG.info "Join the fun at http://localhost:$PORT/landing"
server.join()
LOG.info("Jetty instance has shut down")
}
}
... and a Groovy StopApp class:
package com.example.main
import javax.management.ObjectName
import javax.management.remote.JMXConnectorFactory
import javax.management.remote.JMXServiceURL
/**
* The flip-side of {@link LaunchApp}, this tool locates the running Jetty instance and uses JMX
* to request a graceful shutdown.
*/
class StopApp {
static JMX_PORT = 8085
static JMX_URL = "service:jmx:rmi:///jndi/rmi://localhost:$JMX_PORT/jmxrmi"
public static void main(String[] args) {
println "Shutting down Jetty instance"
def connector = JMXConnectorFactory.connect(new JMXServiceURL(JMX_URL), null)
connector.connect null
def connection = connector.getMBeanServerConnection()
def on = new ObjectName("org.eclipse.jetty.server:type=server,id=0")
connection.invoke on, "stop", null, null
println "Shutdown command sent"
}
}
The only trick is to ensure that LaunchApp's JMX MBean server is exposed for access, so you need the following system properties set:
-Dcom.sun.management.jmxremote.port=8085
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
From http://tapestryjava.blogspot.com/2010/11/starting-and-stopping-jetty-gracefully.html
Opinions expressed by DZone contributors are their own.
Comments