jmx4r 0.0.8: "Through the Looking Glass"
jmx4r 0.0.8 has just been released.
Why "Through the Looking Glass"?
Until this version, jmx4r was a library which made it super easy to write simple Ruby scripts to manage Java applications using JMX.
With this version, the perspective has changed, we went through the looking glass and are now on the other side: jmx4r makes it super easy to directly manage Ruby applications by leveraging JRuby and the Java platform.
A 30-line example is worth 10,000 words:
#!/usr/bin/env jruby
require 'rubygems'
require 'jmx4r'
# a regular Ruby object we want to manage
class Foo < JMX::DynamicMBean
operation "a polite management operation"
parameter :string, "how do you want to be called?"
returns :string
def hello(name="world")
"hello, #{name}!"
end
operation "double the value"
parameter :long
returns :long
def double(value)
value * 2
end
end
# Java objects to register the Ruby object in the platform
import java.lang.management.ManagementFactory
import javax.management.ObjectName
foo = Foo.new
# each managed object needs an unique 'ObjectName'
object_name = ObjectName.new "foo:type=Foo"
ManagementFactory.platform_mbean_server.register_mbean foo, object_name
# we keep the script running to manage it using jconsole
puts "open jconsole to manage foo registered under 'foo:type=Foo'"
gets
ManagementFactory.platform_mbean_server.unregister_mbean object_name
Save this script and run it using JRuby (tested it with version 1.3.0):
$ jruby bean.rb
open jconsole to manage foo registered under 'foo:type=Foo'
That's it: you have a Ruby application which can be managed using any Java management console.
For example, if we start jconsole to manage the bean.rb script:
In the MBeans tab, we can expand Foo to see the management operation:
And we can finally invoke it (e.g. by pushing the hello
or double"
button) and get a result after the method is called on the Ruby object:
How to manage a Ruby object
To be manageable from a management console, the Ruby object must inherit from JMX::DynamicMBean
Since Java is statically typed, you also need to give some hints to help Java calls the Ruby object.
Each method you want to expose as a management operation must be annotated with:
- an
operation
(and an optional description) - a list of
parameter
(with a mandatory type and optional name and description) - a
returns
type
The returns
and parameter
type must be one of :boolean, :byte, :int, :long, :float, :double, :list, :map, :set, :string, and :void
For example, if we have a method which prints the name and age of an user, it can be minimally exposed as:
operation
parameter :string
parameter :int
returns :void
def display(name, age)
puts "#{name} is #{age} years old
end
Exposing Ruby attributes for management is even simpler:
class AttributeTypesMBean < JMX::DynamicMBean
rw_attribute :my_attr, :string, "a read/write String attribute"
r_attribute :another_attr, :int, "a readonly int attribute"
...
end
the rw_attribute
declares a Ruby attribute (using attr_accessor
) which is also exposed for management and can be read and write from a management console. Likewise, r_attribute
declares a read-only Ruby attribute (using attr_reader
) which can only be read from a management console.
DynamicMBean RDoc contains a description of all these annotations.
Finally, the code to register/unregister the Ruby object is taken directly from the Java library using ManagementFactory.platform_mbean_server
to access the Java Platform's MBean Server.
Each managed object must be registered with an unique ObjectName that is created using the javax.management.ObjectName
class (the JMX Best Practices is a good start for an overview of JMX, the umbrella name for management in Java).
Most of this code was taken from the jmx
module of jruby-extras. I fixed some issues with it but, from now on, the remaining bugs are likely written by me!
jmx4r was a simple and small library to write Ruby scripts to manage Java applications.
It is now also a simple and small library to manage Ruby applications.
With the success of JRuby and the rise of Ruby applications running on Java such as Torquebox, GitHub:fi, etc., I believe it can be very useful to leverage the features provided by the Java platform to manage Ruby applications.
As usual, to get this new release, just update the rubygem:
jruby -S gem install jmx4r
and do not hesitate to contribute:
git clone [git://github.com/jmesnil/jmx4r.git][jmx4r]