Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Starting and Stopping Jetty Gracefully with Groovy and JMX

DZone's Guide to

Starting and Stopping Jetty Gracefully with Groovy and JMX

· Java Zone
Free Resource

Download Microservices for Java Developers: A hands-on introduction to frameworks and containers. Brought to you in partnership with Red Hat.

I'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

Download Building Reactive Microservices in Java: Asynchronous and Event-Based Application Design. Brought to you in partnership with Red Hat

Topics:

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}