DZone
Java Zone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
  • Refcardz
  • Trend Reports
  • Webinars
  • Zones
  • |
    • Agile
    • AI
    • Big Data
    • Cloud
    • Database
    • DevOps
    • Integration
    • IoT
    • Java
    • Microservices
    • Open Source
    • Performance
    • Security
    • Web Dev
DZone > Java Zone > Starting and Stopping Jetty Gracefully with Groovy and JMX

Starting and Stopping Jetty Gracefully with Groovy and JMX

Howard Lewis Ship user avatar by
Howard Lewis Ship
·
Nov. 15, 10 · Java Zone · Interview
Like (0)
Save
Tweet
7.86K Views

Join the DZone community and get the full member experience.

Join For Free

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")
}
}
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

Jetty (web server) Groovy (programming language)

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • How to Determine if Microservices Architecture Is Right for Your Business
  • ETL, ELT, and Reverse ETL
  • 5 Steps to Strengthen API Security
  • How BDD Works Well With EDA

Comments

Java Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • MVB Program
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends:

DZone.com is powered by 

AnswerHub logo