Jetty JMX Webservice is a webapp providing a RESTful API to query JMX mbeans and invoke mbean operations without the hassle that comes with RMI. No more arguments with your firewall admin, just a single http port.
That alone might not be a killer feature, but Jetty JMX Webservice also aggregates multiple mbeans having the same ObjectName in the same JVM (e.g. jmx beans for multiple webapps) as well as from multiple jetty instances. That way you’ve a single REST api aggregating JMX mbeans for one or more jetty instances you can use to feed your favourite monitoring system for example.

The whole module is in an early development phase and may contain some rough edges. But we wanted to check for interest of the community early and get some early feedback.

We’ve started a very simple JQuery based webfrontend as a showcase on what the REST api can be used for.

Instance Overview:

A table showing two jetty instances.

Or a realtime memory graph gathering memory consumption from the REST api. This is an accordion like view. You see an accordion line for each node showing the current heap used. You can open each line and get a realtime graph of memory consumption. The memory used in the accordion and the graphs are updated in realtime which is hard to show in a picture:

Realtime memory graph

Pretty cool. Note that this is just a showcase on how the REST api can be used.

URLs Paths of the webservice

/ws/ – index page
/ws/nodes – aggregated basic node information
/ws/mbeans – list of all aggregated mbeans
/ws/mbeans/[mbean objectName] – detailed information about all attributes and operations this mbean offers
/ws/mbeans/[mbean objectName]/attributes – aggregate page containing the values of all attributes of the given mbean
/ws/mbeans/[mbean objectName]/attributes/[attributeName] – aggregated values of a specific attribute
/ws/mbeans/[mbean objectName]/operation/[operationName] – invoke specified operation

Examples URLs:

/ws/mbeans/java.lang:type=Memory
/ws/mbeans/java.lang:type=Memory/operations/gc

How to get it running

Here’s all you need to do to get jetty-jmx-ws running in your jetty instance and some examples how the REST api looks like and how it can be used. Should take less than 15 min.

  1. Checkout the sandbox project
    svn co https://svn.codehaus.org/jetty-contrib/sandbox/jetty-jmx-ws
  2. cd into the new directory and build the project
    cd jetty-jmx-ws && mvn clean install
  3. Make sure you got the [INFO] BUILD SUCCESS message
  4. Copy the war file you’ll find in the projects target directory into the webapps directory of your jetty instance
    cp target/jetty-jmx-ws-[version].war [pathToJetty]/webapps
  5. Access the webapp by browsing to:
    http://[jettyinstanceurl]/jetty-jmx-ws-[version]/ws/
    e.g.:
    http://localhost:8080/jetty-jmx-ws-7.4.1-SNAPSHOT/ws/
  6. You’re done. 🙂

How to use it: Starting point

As it is a RESTful api it will guide you from the base URL to more detailed pages. The base URL will return:

It shows you two URLs.

The first one will guide you through a list of mbeans which is aggregated. This means it’ll show you mbeans which do exist on ALL configured instances. mebans which exist only on a single instance will be filtered out.

The second URL shows you basic node information for all configured nodes:

Howto query a single mbean

This example shows how to let you guide through the REST api to query a specific mbean. This example will guide you through to the memory mbean.

  1. From the base URL follow the link to the mbeans list:
    http://localhost:8080/jetty-jmx-ws-7.4.1-SNAPSHOT/ws/mbeans
  2. Search for the mbean name you’re looking for:
  3. Open the link inside the URL tag
    http://localhost:8080/jetty-jmx-ws-7.4.1-SNAPSHOT/ws/mbeans/java.lang:type=Memory
  4. You’ll get a list of all operations which can be executed on that mbean and all attributes which can be queried:
  5. Besides some information about all operations and attributes you’ll find URLs to invoke operations like:
    http://localhost:8080/jetty-jmx-ws-7.4.1-SNAPSHOT/ws/mbeans/java.lang:type=Memory/operations/gc
    which will invoke a garbage collection.And URLs to display the attributes’ values like:
    http://localhost:8080/jetty-jmx-ws-7.4.1-SNAPSHOT/ws/mbeans/java.lang:type=Memory/attributes/HeapMemoryUsage
    Will show you: 
  6. You can as well get an aggregated view of all attributes for an mbean by just adding attributes to the mbeans url: http://localhost:8080/jetty-jmx-ws-7.4.1-SNAPSHOT/ws/mbeans/java.lang:type=Memory/attributes
    will return: 

Security

It’s a webapp with some servlets. So secure it the same way you would any servlet.

What’s next?

There’s two more features which I didn’t describe. I will write a follow up soon describing how to use them.

  1. You can filter by nodes with QueryParams
  2. Invoke operations whith parameters
  3. Configuration for multiple instances
  4. Get JSON instead of XML by setting accept header

If there’s interest in this project, I will also take care to write some manuals and add them to the wiki pages.

Jetty JMX Webservice

14 thoughts on “Jetty JMX Webservice

  • May 25, 2011 at 5:10 pm
    Permalink

    I really don’t know anything ’bout this maven stuff, but I’m failing after ‘mvn clean install’, on both my Mac and one of my Debian servers:

    –8 [Help 1]
    [ERROR]
    [ERROR] The project org.mortbay.jetty:jetty-jmx-ws:7.4.1-SNAPSHOT (/Users/mike/sandbox/jetty-jmx-ws/pom.xml) has 1 error
    [ERROR] Non-resolvable parent POM: Could not find artifact org.mortbay.jetty:jetty-integration-project:pom:7.4.1-SNAPSHOT in maven2-repository.dev.java.net (http://download.java.net/maven/2/) and ‘parent.relativePath’ points at wrong local POM @ line 6, column 11 -> [Help 2]
    [ERROR]
    [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
    [ERROR] Re-run Maven using the -X switch to enable full debug logging.
    [ERROR]
    [ERROR] For more information about the errors and possible solutions, please read the following articles:
    [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/ProjectBuildingException
    [ERROR] [Help 2] http://cwiki.apache.org/confluence/display/MAVEN/UnresolvableModelException
    –8<–

    Any hints?

  • May 25, 2011 at 9:02 pm
    Permalink

    I’d like to try it out, but when I checked out the source and built it, it complains about not being able to download jetty-integration-project.

    [ERROR] Non-resolvable parent POM: Could not find artifact org.mortbay.jetty:jetty-integration-project:pom:7.4.1-SNAPSHOT in maven2-repository.dev.java.net (http://download.java.net/maven/2/) and ‘parent.relativePath’ points at wrong local POM @ line 6, column 11 -> [Help 2]

    Something wrong with my settings or is it not there? Thanks!

  • May 26, 2011 at 8:26 am
    Permalink

    That’s my fault. I changed the jetty version to a released version and maven should be able to download the dependency now.
    Please do an svn update and try again.

    Please make sure that your jetty-jmx.xml enables remote jmx via rmi and listens to localhost:1099. And that jmx is enabled in your start.ini.

  • May 31, 2011 at 4:42 am
    Permalink

    Hi,

    Please update your feeds at Planet Eclipse to point to this blog ! 🙂

    Thank you.

  • June 8, 2011 at 11:02 pm
    Permalink

    I do a good clean build SUCCESS
    I go to the “http://localhost:8080/jjws/ws/nodes” url

    HTTP ERROR 500

    Problem accessing /jjws/ws/nodes. Reason:

    java.lang.String cannot be cast to javax.management.openmbean.CompositeData
    Caused by:

    java.lang.ClassCastException: java.lang.String cannot be cast to javax.management.openmbean.CompositeData
    at org.mortbay.jetty.jmx.ws.service.impl.AggregateServiceImpl.getMemoryByNode(AggregateServiceImpl.java:84)
    at org.mortbay.jetty.jmx.ws.service.impl.AggregateServiceImpl.getNodes(AggregateServiceImpl.java:63)
    at org.mortbay.jetty.jmx.ws.web.Nodes.getObjectNames(Nodes.java:42)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$TypeOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:168)
    at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:71)
    at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:280)
    at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108)
    at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
    at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84)
    at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1341)
    at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1273)
    at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1223)
    at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1213)
    at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:414)
    at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537)
    at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:699)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:538)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:478)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:119)
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:480)
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:225)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:937)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:406)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:183)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:871)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:117)
    at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:247)
    at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:149)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:110)
    at org.eclipse.jetty.server.Server.handle(Server.java:346)
    at org.eclipse.jetty.server.HttpConnection.handleRequest(HttpConnection.java:589)
    at org.eclipse.jetty.server.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:1048)
    at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:601)
    at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:214)
    at org.eclipse.jetty.server.HttpConnection.handle(HttpConnection.java:411)
    at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:535)
    at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:40)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:529)
    at java.lang.Thread.run(Thread.java:662)

  • June 9, 2011 at 11:59 pm
    Permalink

    Oopsssssss
    Forgot to turn jmx on.

    Life is good now.

  • June 22, 2011 at 1:00 pm
    Permalink

    We’re currently using the standard RMI connector for JMX and does monitoring via HP SiteScope JMX service. In order to monitor through firewalls we have set up fixed ports and the SiteScope service uses URL’s like service:jmx:rmi://:2346/jndi/rmi://:12346/jettyjmx.

    Switching to a HTTP connector would ease overall administration of ports but I wonder how an URL would have to look for a system like SiteScope ?
    I also wonder if this connector would be part of standard Jetty distribution.

    • June 22, 2011 at 1:16 pm
      Permalink

      Hi Per,

      the jmx-ws is as described a new RESTful api forwarding to jmx. So if you want to integrate that in your favourite monitoring tool, you would have to custom build that integration point/interface.
      As described above using this RESTful api will offer you nearly all features you have with standard jmx without the burden to use rmi or the standard jmx interfaces. You can simply do your http requests to gather information, invoke operations, etc.

      Cheers,
      Thomas

      • May 19, 2012 at 6:48 am
        Permalink

        how do I connect to remote JMX bean?
        I looked at the jmxNodes property file, It has localhost:1099

        I believe I can change that to remotehost:remoteport.
        when I connect using jconsole, i have to specify userid/password when connecting to remote JMX.How can that be done in jmxNodes.property?

        • May 21, 2012 at 7:52 am
          Permalink

          Yes, you can simply change it and also add multiple nodes if you want to monitor multiple jetty instances.

          It’s a webapp so you can secure it the same way as any other webapp. For example by defining basic-auth in web.xml.

  • June 22, 2011 at 1:18 pm
    Permalink

    We’d be happy to receive feedback about people trying to use this webservice. If you think this is gonna be useful for you and what your experiences with jmx-ws have been if you tried it. And what you would like to have improved, etc.

    So tell us. 🙂

  • July 15, 2011 at 7:41 pm
    Permalink

    Very nice. Exploring using it as part of a distributed application project.

  • May 21, 2012 at 7:32 pm
    Permalink

    Looks interesting – wondered if you were aware of Jolokia ( http://jolokia.org/ )?
    Seems to fit a similar use case, but they’re a bit further along I think.

  • Pingback:JMiniX JMX console in Jetty | Webtide Blogs

Comments are closed.