a |b |c |d |e |f |g |h |i |j |k |l |m |n |o |p |q |r |s |t |u |v |w |x |y |z |

Apache Commons Modeler

Java Management Extensions (JMX) is an API that facilitates building management applications that can configure, and perform operations on, a server application. In general, each manageable component of the server application is represented by a Management Bean (or MBean, for short). JMX defines three types of MBeans, of which Model MBeans are the most flexible. Model MBeans provide a way to define MBeans for many different components, without having to write a specific MBean implementation class for each one. However, this power comes at a price. It is necessary to set up a substantial amount of metadata about each MBean, including the attributes it should expose (similar to JavaBeans properties), the operations it should make available (similar to calling methods of a Java object via reflection), and other related information. The Modeler component is designed to make this process fairly painless -- the required metadata is configured from an XML description of each Model MBean to be supported. In addition, Modeler provides a factory mechanism to create the actual Model MBean instances themselves.

Related Articles


Jeff Mesnil: JMX Scripts with Eclipse Monkey


Continuing the series about “writing JMX scripts in a dynamic language”, after Ruby (part I& II), let’s do that in JavaScript.

Aside of the use of a different scripting language, this example differs completely from the Ruby one by its context of execution: it will be integrated into Eclipse and called directly from its user interface (using Eclipse Monkeyas the glue).

The example will:

  1. ask graphically the user for a logging level
  2. update all the JVM’s loggers with this level
  3. display all the loggers of the JVM

in 50 lines of code.

This example is simple but it implies several interesting steps:

  • connect to a JMX Server
  • retrieve a MBean
  • retrieve value of MBean attributes
  • invoke operations on the MBean

There are many use cases where you have to perform theses steps in repetition. It’s tedious to do that in a JMX console (e.g. jconsoleor eclipse-jmx) and most of the time, it is not worth writing a Java application.

These use cases beg to be scripted.

We will again use jconsole as our managed java application (see this previous postto start jconsole with all System properties required to manage it remotely).

To run the example:

  1. install Eclipse Monkey
  2. Make sure that Eclipse is running on Java 1.5 or above
  3. copy the script just below and save it as logging_change_level.jsin the scriptsdirectory of an Eclipse project
  4. click on Scripts > Logging > Change levelin Eclipse menu
  5. follow the instruction to install the required DOM
    • only the JMX Monkeyfeature is required
  6. restart Eclipse
  7. click on Scripts > Logging > Change level
  8. in the dialog, input the logging level
  9. all the loggers have been updated with the given level

logging__change__level.js

/*
 * Menu: Logging > Change level
 * DOM: http://eclipse-jmx.googlecode.com/svn/trunk/net.jmesnil.jmx.update/net.jmesnil.jmx.monkey.doms
 */

function main() {
   mbsc = jmx.connect("localhost", 3000)
   logging = mbsc.getMBean("java.util.logging:type=Logging")

   level = ask_level()
   set_all(mbsc, logging, level)
   text = "All loggers are set to " + level + "\n\n"
   text += logger_levels(mbsc, logging)
   show(text)
}

function logger_levels(mbsc, logging) {
   var out = ""
   for each(loggerName in logging.LoggerNames) {
       lvl = mbsc.invoke(logging, "getLoggerLevel",
            [loggerName],
            ["java.lang.String"]);
       out += loggerName + " is at " + lvl + "\n"
   }
   return out
}

function set_all(mbsc, logging, level) {
   for each(loggerName in logging.LoggerNames) {
       mbsc.invoke(logging, "setLoggerLevel",
            [loggerName, level],
            ["java.lang.String", "java.lang.String"])
   }
}

function ask_level() {
   dialog = new Packages.org.eclipse.jface.dialogs.InputDialog(
          window.getShell(), 
          "Logging Level",
          "Which level? (SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST)",
          "INFO", null)
   result = dialog.open()
   if (result == Packages.org.eclipse.jface.window.Window.OK) {
       return dialog.getValue()
   }
}

function show(text) {
   Packages.org.eclipse.jface.dialogs.MessageDialog.openInformation(
           window.getShell(),
           "Update Logging",
           text
       )
} 

code walkthrough

The main()function of the script is:

function main() {
  mbsc = jmx.connect("localhost", 3000)
  logging = mbsc.getMBean("java.util.logging:type=Logging")

   level = ask_level()
   set_all(mbsc, logging, level)
   text = "All loggers are set to " + level + "\n\n"
   text += logger_levels(mbsc, logging)
   show(text)
 } 

where

  • mbsc = jmx.connect("localhost", 3000)creates a mbscobject connected to a local JMX server using the standard JMX Service URL.
  • logging = mbsc.getMBean("java.util.logging:type=Logging")creates a loggingobject representing the LoggingMXBeanused to manage the JVM logging.
  • level = ask_level()opens an Eclipse input dialog where you can input the logging level and returns it as a String.
  • set_all(mbsc, logging, level)sets all the loggers at the given level
  • text += logger_levels(mbsc, logging)returns a String representation of all the loggers and their level
  • show(text)opens an Eclipse message dialog

The interesting methods are logger_levels()and set_all(). In both methods, we retrieve an attribute of a MBean and invoke an operation.

Let’s focus on set_all():

function set_all(mbsc, logging, level) {
   for each(loggerName in logging.LoggerNames) {
       mbsc.invoke(logging, "setLoggerLevel",
            [loggerName, level],
            ["java.lang.String", "java.lang.String"])
   }
} 

loggingrepresents a MBean (it is not a “real” MBean, more on that later) and mbscrepresents a MBeanServerConnection(but it is not a “real” MBeanServerConnection, more on that later).
logging.LoggerNamesreturns the value of the LoggerNamesattribute of the MBean ( note that the *first letter* must be in *upper case*) which is an array of strings.
For each element of this array, we invoke the setLoggerLeveloperation using mbsc.invoke().
This method is very similar to the “real” MBeanServerConnection.invoke()method:

  1. something representing a MBean (instead of an ObjectName)
  2. the MBean operation name
  3. the parameters of the operation
  4. the types of the parameters

jmx: an Eclipse Monkey DOM

What do I mean when I write that loggingis not the “real” LogginMXBeanand that mbscis not the real MBeanServerConnection?

This 2 types of objects are created by the jmxobject in the main()method. This jmxobject is in fact an Eclipse Monkey DOMthat is contributed by the plug-in listed in the DOMdirective at the top of the script:

* DOM: http://eclipse-jmx.googlecode.com/svn/trunk/net.jmesnil.jmx.update/net.jmesnil.jmx.monkey.doms 

This plug-in was included in the “JMX Monkey” feature which was installed the first time you ran this script.

The jmxDOM has a single method connect(host, port)which connects to a JMX Server using the standard JMX Service URL.
The object returned by this method is a ScriptableMBeanServerConnection. This class encapsulates the “real” MBeanServerConnection(still available using the getObject()method) but only exposes its invoke().

It also exposes a getMBean()method which returns a ScriptableMBean. In turn this class exposes the attributes of the MBean as JavaScript attributes.

To sum up, these are the operations you can perform using the jmxDOM:

  • connect to a JMX server: mbsc = jmx.connect(host, port)
  • get a mbean: mbean = mbsc.getMBean(objectName)
  • get the value of a mbean attribute: val = mbean.AttributeName
  • get the “real” mbean server connection and use it: objectNames = mbsc.getObject().queryNames(name, query)
  • invoke an operation on a mbean: mbsc.invoke(mbean, operation, params, param_types)

Conclusion

This script example is simple but quite interesting thanks to its integration with Eclipse.

I believe there is an use for such scripts: repeatable management operations that needs to be tweaked from time to time. It’s tedious to do that with a GUI and it’s even more tedious to write Java applications to do so.

Last year, during EclipseCon’06, I blogged about an use case for scripting a RCP applicationusing Eclipse Monkey. This is a concrete example: I’m using eclipse-jmxto manage Java applications that I develop. When I realize that I perform the same kind of management task, I write a monkey script which automates it.

Next time, you have to perform the same operation on many MBeans or many operations on the same MBean but you think it is not worth to write a Java application to automate it, ask yourselves if it can not be simply automated by a script such as the one in this post.

mbeans
Agent M. Bean is a JMX agent that acts as an MBean application launcher. It includes a lightweight JMX microkernel J2SE application server for hot-deploying MBeans. A variety of MBeans are provided (including an IRC adaptor!) for general consumption.
javamaf
The goal of this project is to make it easy for developers to make their Java applications highly manageable. This project provides several JMX MBeans and utility classes to facilitate management of a Java application.
Swingweb

Swingwebis a web-application framework that enables AWT/Swing application to operate inside a web container and presented as a web application to the web browser, purely in HTML/CSS/javascript. The swing application will render and behave in the web-container the same as it would as a desktop application. There is little knowledge required for the developer to start developing swingweb application as long as they are familiar with swing UI development.

The main goals of the Swingweb framework are to:

  1. Enable true component-based web-application development platform
    Swingweb allows the developer to specify the web-application in terms of UI components and their interactions. The functionality of the web-application is more formally definedas opposed to page-centric model where functionality is composed by gluing the webpages loosely together. Furthermore, the application functionality is more predictable and guaranteed to work as long as all UI components are unit-tested. There will be no more page-management and http session-state manipulation hassle. Once written, the component, either fine-grain like a text-box, or coarse-grain like calendar, will be reusableand save development costs over time.
  2. Use swing UI model for web application development
    Swing component model is one of the best and most-practiced UI modelfor java platform. There should be no learning curvefor most Java developer to pick up web-application development using swingweb. Swingweb tries to make distinction between desktop and web application development as transparentas it could be yet at the same time maintains flexibility on the controls of the look and feel of the web-application through UI component template system.
  3. Allow rapid development using existing GUI editors for web application development
    There are a lot of good tools for swing application development. Most java IDEs (including eclipse) also contain GUI editors. The editors allow the developer to rapidly develop, maintain and changethe application in response to changed requirement.
  4. Save development cost by merging the development process of swing desktop application and (e.g. in-house) web application
    Given the right architecture, the desktop and web application development can be merged into a single process and thus reduces development cost.

Some of the features of Swingweb include the following:

  • Support web-environment with multiple concurrent application sessions
    While most desktop applications are designed to run in a stand-alone jvm, swingweb extended the AWT toolkit implementation so that multiple concurrent application sessionscan run in the web container jvm, yet making each application session isolated so that the running applications will not interfere with each other's operations.
  • Component-oriented architecture that allows developers to enable existing swing component to web environment easily
    Swingweb underlying framework allows developer to control how the interaction and event-input of each component individually. Thus it is very easy to extendan existing swing component (e.g. some third-party widget) so that it can operate in web environment.
  • Flexible template-based approach allowing changing look/functionality of component/application
    The rendering of the each swing components is provided through a template file that is written in jxp template language(essentially java language). Thus it is very easy to control the look and feel of a component as web widget. Furthermore, the template can be configured per component type or per instance.
  • Transparent URL manipulation and session management inside swingweb application
    Swingweb support url manipulationso the developer can customize how the browser url changes as the interface changes. The application can also access and react to url changesusing very simple API. This allow implementation of webapplication that allows bookmarking, back-buttonand other advanced features such as component caching and sharing. There is also API for per session variables.
  • Light-weight, performance focus, and scalable for high traffic web-applications
    The (awt)toolkit implementation utilizes several techniques including lightweight peers, threadless event queue, custom repaint managerto reduce memory footprint and increase the performance of the swing application in the web context. There is also a special deployment mode, share-app mode, which allows sharing of component instancesacross the application sessions for scalability.
  • Natural adaptation of components to the webSome adaptation has been made to the components for the web development - e.g. - FileDialog will upload local files to webserver, all button icons will be buffered and rendered property as <img src=""> tag, all components that uses Graphics2D can be rendered nicely as image (with a flag set of the component) etc.
jsesoft-mmbi
JMX Instrumentor is a tiny Java tool to instrument arbitrary objects as JMX Model MBeans. It inspects the object's class by reflection and constructs the respective ModelMBeanInfo. This information can even be improved by an annotation dedicated to JMX.