Archive for the ‘jmx4r’ Category
jmx4r 0.1.2 has just been released (jmx4r is a JRuby library which makes it super easy to write simple Ruby scripts to manage Java & JRuby applications using JMX).
- it fixes a bug in the
getAttributes() method that is exposed by Ruby objects extending jmx4r’s DynamicMBean class
I introduced the bug but it is one of the rare cases where I would still blame JMX API. Its DynamicMBean interface has
two methods:
getAttribute(String attribute)
getAttributes(String[] attributes)
Following the principle of least surprise, I expected getAttribute(String) to return the value of the attribute and getAttributes(String[]) to return a collection of the attribute values. But that’s not the case. As expected getAttribute(String) returns the value of the attribute but getAttributes(String[]) returns a AttributeList which is a list of Attribute objects (which in turns contains the name and value of an attribute).
jmx4R 0.1.2 fixes the issue and make sure the methods return the correct objects.
JMX is one of my favorite Java API, simple, flexible and powerful at the same time. Its evolution made it both a bit uglier and more convenient (I wish open types were more simpler to use and less verbose to declare). Providing a library to use JMX in JRuby applications is the perfect match between a simple and powerful library (JMX) and a simple and powerful language (Ruby) on a simple and powerful platform (JVM).
From time to time, I receive mails inquiring about the status of jmx4r.
I no longer use jmx4r in my daily job and it is not actively developed. However it is actively maintained. If you find bugs, I can release a new version quite fast. jmx4r users are awesome and most of the time, they provide patches when they report bugs.
If you have ideas for improvements, do not hesitate to send me a mail or fork the project. Most recent contributions were done through forks on GitHub.
Once again, thanks to all the contributors and users who help make jmx4r even more useful!
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
An user reported an issue with jmx4r because he was not able to access a MBean attribute.
See for example attribute names under the amx:j2eeType=X-MonitoringDottedNames,name=na mbean of a GlassFish instance.
Trying to get the value of an attribute like server.http_service.file_cache.maxentries_lastsampletime doesn’t work.
He is right that jmx4r does not work with dotted attributes. For example, this code will fail:
server = JMX::MBean.find_by_name "amx:j2eeType=X-MonitoringDottedNames,name=na"
puts server.http_service.file_cache.maxentries_lastsampletime
JMX supports dotted attributes but they can not be used directly with jmx4r because of Ruby syntax.
Ruby will read server.http_service.file_cache.maxentries_lastsampletime and will rightfully call http_service on the
server object first. But there is no such method or attribute and the call will fail.
To circumvent this issue and be able to use jmx4r with dotted MBean attributes, you can use Ruby Object#send.
Instead of
server.http_service.file_cache.maxentries_lastsampletime
you will have to use
server.send("http_service.file_cache.maxentries_lastsampletime")
This looks ugly but it works.
The user proposed to have jmx4r objects implement [] and work like a Hash to support dotted names.
I am not convinced that such edge cases are worth supporting [] but if you think otherwise, do not hesitate to vote for this feature and I will add it to jmx4r.
jmx4r 0.1.0 has just been released (jmx4r is a JRuby library which makes it super easy to write simple Ruby scripts to manage Java applications using JMX).
- fixed compatibility with Rake 0.8.7 (thanks Dan!)
- fixed dynamic mbean issues where attributes and methods were added to all the dynamic mbeans in the thread (thanks Munesse!)
There is also two new features:
- support for Java CamelCase style in addition to Ruby snake_case (thanks again to Dan)
logging = JMX::MBean.find_by_name "java.util.logging:type=Logging"
# Ruby syntax works
logging.set_logger_level "global", "FINEST"
# Java syntax works too
logging.setLoggerLevel "global", "FINEST"
- Connection to a local JVM (thanks to Mr ohtsuka).
You can now connect to a JVM running on the same machine without adding the
com.sun.management.jmxremote system properties.
For example, start an instance of jconsole without any additional system properties:
You can now manage this Java application locally:
require 'rubygems'
require 'jmx4r'
# :command is a regexp corresponding to the Java process to connect to
JMX::MBean.establish_connection :command => /JConsole/
memory = JMX::MBean.find_by_name "java.lang:type=Memory"
memory.gc
In addition to the previous :host, :port and :url arguments that you can pass to establish a JMX connection, there is now :command which must be a regular expression corresponding to the local Java process you want to connect to. You can find the name of the process using jps:
$ jps
4255 JConsole
4395 Jps
You can connect to a local Java application running on Java 5 or 6. Is someone interested to contribute support for JDK7 too?
Once again, thanks to all the contributors and users who help make jmx4r even more useful!
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 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]

I noticed today that O’Reilly just released JRuby Cookbook. I have a few ideas I’d like to implement using JRuby and I was browsing the table of contents to check if the book could be helpful.
I was pleasantly surprised to see that it contains a section about “Performing Remote Management with JMX” using jmx4r (you can read a preview of the section by expanding it from the table of contents).
I’m obviously biased but I deeply believe that a small library such as jmx4r (less than 200 SLOC for the main file and 1/3 are comments) shows what the combination of Ruby and Java can achieve.
JRuby leverages the strong Java runtime (with its garbage collection and hotspot) and allows to access a wide range of Java libraries with all the strengths of the Ruby language.
For example, in jmx4r case, I extensively use Ruby metaprogramming toolset to dynamically create the properties and methods correponding to the MBean attributes and operations.
There are also other stories which demonstrates what JRuby brings to the table coming from the C-Ruby world.
I’m looking forward to read this cookbook and write some ruby code built on top of the Java platform.
jmx4r 0.0.6 has just been released (jmx4r is a JRuby library which makes it super easy to write simple Ruby scripts to manage Java applications using JMX).
This release adds helper methods to make it more natural to work with TabularData attributes and ObjectName properties
Iterate over TabularData attribute
TabularData attributes now behave like regular Ruby Enumerable:
#!/usr/bin/env jruby
require 'rubygems'
require 'jmx4r'
runtime = JMX::MBean.find_by_name "java.lang:type=Runtime"
# runtime.system_properties is a TabularData
runtime.system_properties.each do | sysprop |
puts "#{sysprop["key"]} = #{sysprop["value"]}"
end
ObjectName properties
ObjectName properties can now be accessed using the [] method:
#!/usr/bin/env jruby
require 'rubygems'
require 'jmx4r'
require 'jconsole'
mem_pools = JMX::MBean.find_all_by_name "java.lang:type=MemoryPool,*"
mem_pools.each do |pool|
# print the 'name' property of the pool's ObjectName
puts pool.object_name["name"]
end
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
From Tim Koopmans:
After getting nowhere with lack luster HP support, I turned to the power of the Open Source community and got a very simple script up and running to remotely monitor Weblogic JVM Performance and JMS queues using JMX and JRuby.
[...]
This script will enumerate JVM performance and also JMS queue depths in around 50 lines of code
That’s a good example of the conciseness that JRuby brings to the Java platform: in 50 lines of code, Tim connects to a remote Weblogic MBean server, retrieves attributes about memory usage and JMS queue and stores them in a CSV file.
jmx4r 0.0.5 has just been released (jmx4r is a JRuby library which makes it super easy to write simple Ruby scripts to manage Java applications using JMX).
There is only one enhancement to this release but it is an important one: you can now specify a custom JMX URL to connect to a MBean Server.
Before this release, the URL was hard-wired to connect using the JMX URL defined by Sun service:jmx:rmi:///jndi/rmi://#{host}:#{port}/jmxrmi.
This means it was not possible to use jmx4r to connect to a MBean server which used another URL or another connector that RMI/JRMP.
With this release, you can now fully specify the url:
url = "service:jmx:rmi:///jndi/iiop://node1:7001/weblogic.management.mbeanservers.runtime"
JMX::MBean.establish_connection :url => url
As an example, the code above can be used to connect to a Weblogic server using RMI/IIOP.
When the :url argument is used, :hostand :port arguments are ignored. If you’re connecting to a Sun JRE, it is still simpler to specify only :host & :port though.
This enhancement was proposed by Tim Koopmans. Thanks Tim!
As usual, to get this new release, just update the rubygem:
jruby -S gem install jmx4r
I use Subversion for my daily work (and CVS before that) but I’ve never used a distributed VCS before.
One of my ex-colleagues, Marc, explained to me all the advantages of these systems but I never took the time to play with them.
With all the increasing noise about Git and Mercurial, I’m now curious to learn more about it.
Since I learn better by practicing, I moved one of my little projects, jmx4r, from Subversion to Git and hosted it on GitHub.
I don’t use jmx4r at the moment and I don’t plan to develop it more (less features is the new black). However, if you have requests for a new feature or enhancement (or bugs), do not hesitate to fill an issue on the tracker.
Or better, clone the Git project:
git clone git://github.com/jmesnil/jmx4r.git
and start hacking it!
P.S.:
With the recent release of JRuby 1.1, I also checked that the latest version of jmx4r had no regression.
Congratulation to the JRuby team for the performance boost since version 1.0!
jmx4r 0.0.4 has just been released.
jmx4r is a JRuby library which makes it super easy to write simple Ruby scripts to manage Java applications using JMX.
To get this new release, just update the rubygem: jruby -S gem install jmx4r
All contributions to this new release were done by Skaar:
- CompositeData behave like regular read-only Ruby Hash
- custom classes can be loaded by `require` statements
- custom JMX credentials are supported
(more…)