<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;A0cASH4_fSp7ImA9WhRbF04.&quot;"><id>tag:blogger.com,1999:blog-11251261</id><updated>2012-02-08T17:10:49.045-05:00</updated><category term="Java Python Graphite JMX" /><category term="GroovyMX" /><category term="gmx" /><category term="Java" /><category term="JMX" /><category term="Groovy" /><title>See All. Hear All.</title><subtitle type="html" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://seeallhearall.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://seeallhearall.blogspot.com/" /><author><name>nickman</name><uri>http://www.blogger.com/profile/09238427833396441114</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>12</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/blogspot/lxpdT" /><feedburner:info uri="blogspot/lxpdt" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;CUcBSHY-cSp7ImA9WhRVGE4.&quot;"><id>tag:blogger.com,1999:blog-11251261.post-2515145142763721360</id><published>2012-01-17T10:08:00.002-05:00</published><updated>2012-01-17T15:44:19.859-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-17T15:44:19.859-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="GroovyMX" /><category scheme="http://www.blogger.com/atom/ns#" term="gmx" /><category scheme="http://www.blogger.com/atom/ns#" term="Groovy" /><category scheme="http://www.blogger.com/atom/ns#" term="JMX" /><title>GroovyMX: New Remote JVM Test Cases</title><content type="html">I just completed a check in to &lt;a href="https://github.com/nickman/GroovyMX" target="_blank"&gt;gmx &lt;/a&gt;with a small number of critical test cases.&lt;br /&gt;
I am attempting to make gmx a Groovy oriented but Java usable API, so for the most part, each logical test case has a Java and a Groovy version. Here's an example of a Groovy test:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;b&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void testRemoteClosureForMBeanCountAndDomains() throws Exception {&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;b&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; def port = 18900;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;b&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; def gmx = null;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;b&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; def jvmProcess = null;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;b&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; try {&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;b&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; jvmProcess = JVMLauncher.newJVMLauncher().timeout(120000).basicPortJmx(port).start();&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;b&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; gmx = Gmx.remote(jmxUrl(port));&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;b&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; def remoteDomains = gmx.exec({ return it.getDomains();});&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;b&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; def domains = gmx.getDomains();&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;b&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Assert.assertArrayEquals("Domain array", domains, remoteDomains);&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;b&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; def remoteMBeanCount = gmx.exec({ return it.getMBeanCount();});&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;b&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; def mbeanCount = gmx.getMBeanCount();&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;b&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Assert.assertEquals("MBean Count", mbeanCount, remoteMBeanCount);&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;b&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; } finally {&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;b&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if(gmx!=null) try { gmx.close(); } catch (Exception e) {}&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;b&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if(jvmProcess!=null) try { jvmProcess.destroy(); } catch (Exception e) {}&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;b&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;b&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
In a nutshell, this test:&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Starts a new JVM with&amp;nbsp; the JMX management agent enabled.&lt;/li&gt;
&lt;li value="2"&gt;Retrieves the MBeanServer's MBean domains using a remote JMX call and then using a remoted closure. Verifies they're equal.&lt;/li&gt;
&lt;li value="2"&gt;Retrieves the MBeanServer's MBean count using a remote JMX call and then using a remoted closure. Verifies they're equal.&lt;br /&gt;
  &lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;

&lt;br /&gt;
The latest snapshot is available here:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://repository-helios.forge.cloudbees.com/snapshot/org/helios/gmx/1.0-SNAPSHOT/gmx-1.0-SNAPSHOT.jar" target="_blank"&gt;Gmx Jar&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://repository-helios.forge.cloudbees.com/snapshot/org/helios/gmx/1.0-SNAPSHOT/gmx-1.0-SNAPSHOT-jar-with-dependencies.jar" target="_blank"&gt;Gmx Jar with Dependencies&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&amp;nbsp;Of course, these tests raised a bunch of issues which I am in arrears entering into Github. If you encounter any issues, please leave me some feedback.&lt;br /&gt;
&lt;br /&gt;
//Nicholas&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11251261-2515145142763721360?l=seeallhearall.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/lxpdT/~4/-0ktQwdNHhU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://seeallhearall.blogspot.com/feeds/2515145142763721360/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=11251261&amp;postID=2515145142763721360&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/11251261/posts/default/2515145142763721360?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/11251261/posts/default/2515145142763721360?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/lxpdT/~3/-0ktQwdNHhU/groovymx-new-remote-jvm-test-cases.html" title="GroovyMX: New Remote JVM Test Cases" /><author><name>nickman</name><uri>http://www.blogger.com/profile/09238427833396441114</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://seeallhearall.blogspot.com/2012/01/groovymx-new-remote-jvm-test-cases.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcMRXw8eSp7ImA9WhRVGE4.&quot;"><id>tag:blogger.com,1999:blog-11251261.post-6416346987324713289</id><published>2012-01-13T17:14:00.000-05:00</published><updated>2012-01-17T15:44:44.271-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-17T15:44:44.271-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="GroovyMX" /><category scheme="http://www.blogger.com/atom/ns#" term="gmx" /><category scheme="http://www.blogger.com/atom/ns#" term="Groovy" /><category scheme="http://www.blogger.com/atom/ns#" term="JMX" /><title>Remoting Groovy with Generated Closures</title><content type="html">On attempting to implement remote closure execution in &lt;a href="https://github.com/nickman/GroovyMX" target="_blank"&gt;Gmx&lt;/a&gt;, I envisioned simply generating a closure on the fly and passing it over the wire to a remote Gmx counterpart.&lt;br /&gt;
In my mind, it looked a bit like this very simple example that would print &lt;b&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;"Hello Jupiter"&lt;/span&gt;&lt;/b&gt; to the standard out on the target remote server:&lt;br /&gt;
&lt;script src="https://gist.github.com/1606791.js"&gt;
 
&lt;/script&gt;
&lt;br /&gt;
&lt;br /&gt;
This is the simplest version of the idea, and so serves as a good proof of concept.&lt;br /&gt;
&lt;br /&gt;
Gmx already has a lot of the plumbing in place, namely:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;The ReverseClassLoader service spins up an HTTP server to provide remote class loading to foreign MBeanServers and performs an acceptable job of locating and serving the bytecode (in the form of a byte[]) to requesting classloaders.&lt;/li&gt;
&lt;li&gt;Gmx automatically detects when remoting will be required and starts the ReverseClassLoader and installs the remote counterpart (RemotableMBeanServer) on the foreign MBeanServer. (This means that some of the code in this &lt;a href="https://gist.github.com/1572517" target="_blank"&gt;example &lt;/a&gt;is redundant).&lt;/li&gt;
&lt;/ul&gt;
The major barrier I ran into was discovering that it is quite difficult to acquire the bytecode (the class representation in the form of bytes) of a closure compiled on the fly. Excuse my use of an imprecise term like "on the fly". What I mean is that if a closure undergoes a formal compilation process, such as using &lt;a href="http://groovy.codehaus.org/The+groovyc+Ant+Task" target="_blank"&gt;groovyc &lt;/a&gt;or a &lt;a href="http://www.jarvana.com/jarvana/view/org/codehaus/groovy/groovy/1.6.0/groovy-1.6.0-javadoc.jar%21/org/codehaus/groovy/control/CompilationUnit.html" target="_blank"&gt;CompilationUnit&lt;/a&gt;, then the class&amp;nbsp;itself is accessible from the java code source URL in the form of a stream of bytes. However, if you define an inline closure in an inline script and execute it (such as you might in &lt;a href="http://groovy.codehaus.org/Groovy+Console" target="_blank"&gt;GroovyConsole&lt;/a&gt;),&amp;nbsp; the class appears to have a "fake" code source URL that cannot be read from. I am not that familiar with the internals of Groovy so this needs further explanation by way of an example:&lt;br /&gt;
&lt;script src="https://gist.github.com/1606935.js"&gt;
 
&lt;/script&gt;
&lt;br /&gt;
&lt;br /&gt;
The output of this script, when run in GroovyConsole, is as follows:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: x-small;"&gt;&lt;b&gt;Class [Name:ClosureFactory$_getClosure_closure1] Bytes:1192 Interfaces: [interface org.codehaus.groovy.runtime.GeneratedClosure]&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: x-small;"&gt;&lt;b&gt;Hello Venus&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: x-small;"&gt;&lt;b&gt;Exception:/groovy/shell (The system cannot find the file specified)&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: x-small;"&gt;&lt;b&gt;Class [Name:ConsoleScript5$_run_closure1] Bytes:[] Interfaces: [interface org.codehaus.groovy.runtime.GeneratedClosure]&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;b&gt;&lt;span style="font-size: x-small;"&gt;Hello Jupiter&lt;/span&gt;&amp;nbsp;&lt;/b&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;br /&gt;
&lt;br /&gt;
In lines 4..6, the example defines a class that creates a closure and returns it from a call to &lt;i&gt;getClosure()&lt;/i&gt;. Using the &lt;i&gt;CompilationUnit &lt;/i&gt;is the equivalent of using &lt;b&gt;groovyc&lt;/b&gt;. 
When the byte code of the closure is read using &lt;span style="font-size: x-small;"&gt;&lt;b&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;clozure.getClass().getProtectionDomain().getCodeSource().getLocation().getBytes()&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;. In the first instance, this is successful.

However, when script defines an "&lt;i&gt;on the fly&lt;/i&gt;" closure on line 16  (the closure works fine, as can be seen on line 26), the same method does not work. In support of this, 
the bytecode for the "compiled" closure is writen to disk. The value of the URL returned by &lt;span style="font-size: x-small;"&gt;&lt;b&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;clozureClass.getProtectionDomain().getCodeSource().getLocation()&lt;/span&gt;&lt;/b&gt;&lt;/span&gt; is &lt;b&gt;file:/home/nwhitehe/groovy/groovy-1.8.5/./&lt;/b&gt;
and the following can be seen in that directory:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;b&gt;&lt;span style="font-size: x-small;"&gt;-rw-r--r--  1 nwhitehe nwhitehe  5893 2012-01-13 11:54 ClosureFactory.class&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;b&gt;&lt;span style="font-size: x-small;"&gt;-rw-r--r--  1 nwhitehe nwhitehe  2454 2012-01-13 11:54 ClosureFactory$_getClosure_closure1.class&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;br /&gt;
For the "&lt;i&gt;on the fly&lt;/i&gt;" closure on the other hand, the script gets an exception when attempting to read the bytes from the code source URL pointing to a file &lt;b&gt;/groovy/shell&lt;/b&gt; which does not exist. The bytecode disappears off into the aether.&lt;br /&gt;
&lt;br /&gt;
There are a few hints on this challenge in a &lt;a href="http://jira.codehaus.org/browse/GROOVY-4583" target="_blank"&gt;Jira ticket&lt;/a&gt; filed at the end of 2010 titled &lt;b&gt;Ability to get class bytes of closures at runtime, including nested closures (for remote control)&lt;/b&gt;. &lt;a href="http://groovy.codehaus.org/modules/remote/" target="_blank"&gt;RemoteControl&lt;/a&gt; is a groovy package for groovy closure remoting, so this seemed like a good place to start, but the documentation [more concisely than I did above] alerts the reader to the same problem:&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;i&gt;The remote execution mechanism works by sending the definition of the 
closure class to the server. It does this by finding the corresponding &lt;code&gt;.class&lt;/code&gt; file for the closure on the class path. This means that there must be a &lt;code&gt;.class&lt;/code&gt;
 file for the closure on the class path for the closure to be able to be
 remotely executed. Closure's whose class has been generated dynamically
 at runtime are currently not supported.&lt;/i&gt;&lt;/blockquote&gt;
The Jira issue also points to a &lt;a href="http://groovyconsole.appspot.com/script/430001" target="_blank"&gt;script by Guillaume Laforge&lt;/a&gt; that outlines a method of finding nested closures with an advisory that this might be useful in resolving the problem, but the script uses a &lt;i&gt;CompilationUnit&lt;/i&gt; to acquire the bytecode so it was not clear to me if that strategy would work.&lt;br /&gt;
&lt;br /&gt;
Aside from using the &lt;b&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Class/ProtectionDomain/CodeSource/Location.getBytes&lt;/span&gt;&lt;/span&gt;&lt;/b&gt; method to get class bytecode, another path I have used is &lt;a href="http://www.csg.is.titech.ac.jp/%7Echiba/javassist/" target="_blank"&gt;Javassist &lt;/a&gt;which did not work, returning a null &lt;a href="http://www.csg.is.titech.ac.jp/%7Echiba/javassist/html/javassist/CtClass.html" target="_blank"&gt;CtClass &lt;/a&gt;when requested from the &lt;a href="http://www.csg.is.titech.ac.jp/%7Echiba/javassist/html/javassist/ClassPool.html" target="_blank"&gt;ClassPool&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
The solution that ended up working was using a &lt;a href="http://docs.oracle.com/javase/6/docs/api/java/lang/instrument/ClassFileTransformer.html" target="_blank"&gt;ClassFileTransformer&lt;/a&gt;. This interface is defined in the &lt;a href="http://docs.oracle.com/javase/6/docs/api/java/lang/instrument/package-summary.html" target="_blank"&gt;java.lang.instrument&lt;/a&gt; package and instance of it can be registered with the JVM's &lt;a href="http://docs.oracle.com/javase/6/docs/api/java/lang/instrument/Instrumentation.html" target="_blank"&gt;Instrumentation&lt;/a&gt; &lt;br /&gt;
instance. It has a single method:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) &lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Accordingly, a ClassFileTransformer can provide the bytecode of a class. For our purposes, it needs to:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Be registered before the class loads or be invoked by a request to retransform the target class.&lt;/li&gt;
&lt;li&gt;Filters out the class that has been targeted.&lt;/li&gt;
&lt;/ul&gt;
The following is a contrived example that retrieves a flat (i.e. no nested closures) closure's class byte code. The instrumentation instance is provided by a Gmx utility class called &lt;a href="https://github.com/nickman/GroovyMX/blob/master/gmx/src/main/java/org/helios/gmx/classloading/ByteCodeRepository.java" target="_blank"&gt;ByteCodeRepository&lt;/a&gt;. (More on that later).&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1608660.js"&gt;
 
&lt;/script&gt;
&lt;br /&gt;
In short, the class file transformer captures the bytecode of the class it is configured to capture. Once the bytecode has been captured, the transformer is unregistered. In order to trigger
a call to the transformer, the instrumentation instance requests a retransform on the closure's class.

Acquiring an instrumentation can be simplified, but the underlying mechanics are complicated. The JVM's instrumentation instance is not automatically created or available. It is typically created
when the JVM is started with a &lt;b&gt;-javaagent&lt;/b&gt; JVM startup option.&lt;br /&gt;
&lt;br /&gt;
Alternatively, it is possible to use the&lt;a href="http://docs.oracle.com/javase/6/docs/jdk/api/attach/spec/index.html" target="_blank"&gt; Java Attach API&lt;/a&gt; to load a Java Agent into a running JVM which will trigger the creation of an
instrumentation instance. This step is implemented by the Gmx utility class &lt;a href="https://github.com/nickman/GroovyMX/blob/master/gmx/src/main/java/org/helios/vm/agent/LocalAgentInstaller.java" target="_blank"&gt;LocalAgentInstaller&lt;/a&gt;'s static method &lt;span style="font-size: x-small;"&gt;&lt;b&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;getInstrumentation()&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
That's pretty much all that is required to get a reference to the instrumentation with some caveats:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;The Attach API is only supported in Java 1.6+&lt;/li&gt;
&lt;li&gt;The Attach API is variably implemented by different JVMs. You may have trouble with IBM JVMs, for example.&lt;/li&gt;
&lt;li&gt;The Attach API is contained in the JDK's tools.jar so if you're using the JRE, you need to specifically add tools.jar to the classpath.&lt;/li&gt;
&lt;/ul&gt;
Gmx uses a reflective wrapper around the Attach API to avoid sticky compilation sores, but the details can be seen in the eponymous classes in the &lt;a href="https://github.com/nickman/GroovyMX/tree/master/gmx/src/main/java/org/helios/vm"&gt;org.helios.vm&lt;/a&gt; package.&lt;br /&gt;
&lt;br /&gt;
The next piece of Gmx is the &lt;a href="https://github.com/nickman/GroovyMX/blob/master/gmx/src/main/java/org/helios/gmx/classloading/ByteCodeRepository.java"&gt;ByteCodeRepository &lt;/a&gt;class. It is a singleton and its functionality is as follows:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;It is a ClassFileTransformer that targets classes that implement &lt;a href="http://www.jarvana.com/jarvana/view/org/codehaus/groovy/groovy/1.8.3/groovy-1.8.3-javadoc.jar%21/org/codehaus/groovy/runtime/GeneratedClosure.html" target="_blank"&gt;org.codehaus.groovy.runtime.GeneratedClosure&lt;/a&gt;. These are typically the closures we're looking for. In my parlance, &lt;i&gt;GeneratedClosure&lt;/i&gt; means "compiled on the fly". See &lt;a href="https://gist.github.com/1608424" target="_blank"&gt;this gist&lt;/a&gt; for the transformer basics.&lt;/li&gt;
&lt;li&gt;It is a caching repository and cross-indexer for closure classes, bytecode and class names (binary and resource).&lt;/li&gt;
&lt;li&gt;It automatically loads an instrumentation instance, so one can ignore the LocalAgentInstaller when using the ByteCodeRepository.&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
Capturing a closure's bytecode is now siplified to: 
&lt;br /&gt;
&lt;script src="https://gist.github.com/1608381.js"&gt;
 
&lt;/script&gt;
&lt;br /&gt;
&lt;br /&gt;
There's one subtlety left [that will be discussed here] in the quest to get bytecode for remoting closures and that's the rider on the Groovy Jira issue I mentioned, namely "&lt;i&gt;including nested closures&lt;/i&gt;".
Consider a closure like this that prints the declared methos signatures methods for each class in an array:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: x-small;"&gt;&lt;b&gt;def Class[] classes = .....;&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: x-small;"&gt;&lt;b&gt;classes.each() {&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: x-small;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; it.getDeclaredMethods().each() {&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: x-small;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; println it.toGenericString();&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: x-small;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: x-small;"&gt;&lt;b&gt;}&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;br /&gt;
That's a closure within a closure, and they're two different classes. The bytecode for the outer closure does not contain the bytecode for the inner, so the earlier examples have hidden this problem. 
The class file transformer will still see the inner closure, and even though the name of the inner closure class is not as obvious (we could derive or guess it), here's why you don't need it:&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;For the pruposes of remoting, so long at the ByteCodeRepository is installed, it will have captured all closures and indexed them by class name. When the remote class loader gets a serialized
closure to invoke, it will surely know and will request each class from the ReverseClassLoader, which in turn looks them up in the ByteCodeRepository.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;The following code prints (among other things that my optimizing editor has elided) the names of the loaded generated closures in this modified example.&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1608875.js"&gt;
 
&lt;/script&gt;
&lt;br /&gt;
The output is:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;b&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Generated Closure: ClosureFactory3$_getClosure_closure1&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;b&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Generated Closure: ClosureFactory3$_getClosure_closure1_closure2&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
All this nonsense was dedicated to getting &lt;i&gt;all &lt;/i&gt;the bytecode necessary to remote closures, which I have not addressed at all, but I will in the next post.&lt;br /&gt;
&lt;br /&gt;
Cheers.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11251261-6416346987324713289?l=seeallhearall.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/lxpdT/~4/NuR6pl6k_LQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://seeallhearall.blogspot.com/feeds/6416346987324713289/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=11251261&amp;postID=6416346987324713289&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/11251261/posts/default/6416346987324713289?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/11251261/posts/default/6416346987324713289?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/lxpdT/~3/NuR6pl6k_LQ/remoting-groovy-with-generated-closures.html" title="Remoting Groovy with Generated Closures" /><author><name>nickman</name><uri>http://www.blogger.com/profile/09238427833396441114</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://seeallhearall.blogspot.com/2012/01/remoting-groovy-with-generated-closures.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcMRXw9fyp7ImA9WhRVGE4.&quot;"><id>tag:blogger.com,1999:blog-11251261.post-1784822801782775576</id><published>2012-01-06T13:55:00.000-05:00</published><updated>2012-01-17T15:44:44.267-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-17T15:44:44.267-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="GroovyMX" /><category scheme="http://www.blogger.com/atom/ns#" term="gmx" /><category scheme="http://www.blogger.com/atom/ns#" term="Groovy" /><category scheme="http://www.blogger.com/atom/ns#" term="JMX" /><title>GroovyMX: A Groovy JMX Client</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://github.com/nickman/GroovyMX/blob/master/content/img/gmx-160-X-160.png?raw=true" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="https://github.com/nickman/GroovyMX/blob/master/content/img/gmx-160-X-160.png?raw=true" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
I bootstrapped a new project on &lt;a href="https://github.com/" target="_blank"&gt;Github &lt;/a&gt;called &lt;a href="https://github.com/nickman/GroovyMX" target="_blank"&gt;GroovyMX&lt;/a&gt; (or just &lt;b&gt;gmx&lt;/b&gt;). It is a monitoring oriented API but you may find it useful for various things. In the spirit of &lt;a href="http://docs.codehaus.org/display/GROOVY/Tutorial+6+-+Groovy+SQL" target="_blank"&gt;Groovy SQL&lt;/a&gt;, I am attempting to provide a JMX client API that is rich in functionality, terse in code and that extends the natural abilities of the native Java client.&lt;br /&gt;
&lt;br /&gt;
This is a quick example which demonstrates how to connect to a remote MBeanServer and list the committed memory in bytes of each of the JVM's Memory Pools:&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1571105.js"&gt;
&lt;/script&gt;
&lt;br /&gt;
The output of this script is:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;pre&gt;&lt;b&gt;&lt;code&gt;java.lang:type=MemoryPool,name=PS Eden Space:  402653184
java.lang:type=MemoryPool,name=PS Survivor Space:   16777216
java.lang:type=MemoryPool,name=Code Cache:  3407872
java.lang:type=MemoryPool,name=PS Perm Gen: 84738048
java.lang:type=MemoryPool,name=PS Old Gen:  268435456&lt;/code&gt;&lt;/b&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;&amp;nbsp;&lt;/code&gt;&lt;/pre&gt;
Briefly,what this code is doing:&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;This is usually the only import you will need.&lt;/li&gt;
&lt;li&gt;The &lt;a href="https://github.com/nickman/GroovyMX/blob/master/gmx/src/main/java/org/helios/gmx/Gmx.java" target="_blank"&gt;Gmx &lt;/a&gt;class represents an &lt;a href="http://docs.oracle.com/javase/1.5.0/docs/api/javax/management/MBeanServer.html" target="_blank"&gt;MBeanServer&lt;/a&gt;, or more specifically, an &lt;a href="http://docs.oracle.com/javase/1.5.0/docs/api/javax/management/MBeanServerConnection.html" target="_blank"&gt;MBeanServerConnection&lt;/a&gt;. There are a few ways to acquire one, depending on the situation, but in this case, I am connecting to a remote MBeanServer using its &lt;a href="http://docs.oracle.com/javase/1.5.0/docs/api/javax/management/remote/JMXServiceURL.html" target="_blank"&gt;JMXServiceURL&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;b&gt;mbeans&lt;/b&gt; method has several overloads. In this case, I am providing an &lt;a href="http://docs.oracle.com/javase/1.5.0/docs/api/javax/management/ObjectName.html" target="_blank"&gt;ObjectName &lt;/a&gt;pattern that will match to all the JVM's &lt;a href="http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/management/MemoryPoolMXBean.html" target="_blank"&gt;MemoryPool MXBeans&lt;/a&gt;, and a closure which executes for each ObjectName returned.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;The closure is passed an instance of a &lt;a href="https://github.com/nickman/GroovyMX/blob/master/gmx/src/main/java/org/helios/gmx/MetaMBean.java" target="_blank"&gt;MetaMBean &lt;/a&gt;which is notionally a proxy that combines the ObjectName of the MBean that it represents, and a MBeanServerConnection to the MBeanServer where the MBean is registered (the Gmx). In as much as possible, MetaMBeans act just like regular Pojos (or Pogos)&amp;nbsp; so the MBean attributes are accessed as simple properties and MBean operations are invoked like regular methods.&lt;/li&gt;
&lt;li&gt;The MetaMBean also has various &lt;i&gt;local&lt;/i&gt; properties which are also accessed as simple properties in a Pogo. An example of this is &lt;b&gt;objectName&lt;/b&gt; in line 4.&lt;/li&gt;
&lt;li&gt;The MemoryPool MBeans publish an attribute called &lt;b&gt;Usage&lt;/b&gt; which is an instance of &lt;a href="http://docs.oracle.com/javase/1.5.0/docs/api/javax/management/openmbean/CompositeData.html" target="_blank"&gt;CompositeData&lt;/a&gt;. Fortunately, Groovy allows the simple reference of the composite sub-values by simple dot notation so the expression &lt;b&gt;it.Usage.committed&lt;/b&gt; retrieves the nested value from the &lt;b&gt;Usage&lt;/b&gt; composite structure that is keyed by the key &lt;b&gt;committed&lt;/b&gt;.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Keen observers might wonder why &lt;b&gt;Usage&lt;/b&gt; is cased that way. This is because the Groovy property specifier &lt;i&gt;Usage&lt;/i&gt; is directly mapped to the MemoryPool MBean attribute &lt;i&gt;Usage&lt;/i&gt;. Since it is perfectly legal for an MBean to have two separate attributes &lt;i&gt;Foo&lt;/i&gt; and &lt;i&gt;foo&lt;/i&gt;, the MetaMBean only honors the correctly specified case.&lt;/li&gt;
&lt;/ol&gt;
One of the tricky parts of making MetaMBean behave like a regular Pojo is that MBean operation invocations &lt;i&gt;require&lt;/i&gt; the exact signature of the operation to be passed as an argument, which is very exacting and JMX can be quite fussy in this regard. Unlike regular Java and Groovy, there is no implicit [un/]boxing or inheritance easing done on your behalf. Consider these signature pairs:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;b&gt;void foo(int)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; void foo(Integer)&lt;/b&gt;&lt;/div&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;b&gt;void log(CharSequence)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; void log(String)&lt;/b&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;br /&gt;
If these were &lt;a href="http://docs.oracle.com/javase/1.5.0/docs/api/javax/management/MBeanOperationInfo.html" target="_blank"&gt;MBeanOperation&lt;/a&gt;s, they would represent two different signatures, so the tricky part is inspecting the MetaMBean invocation name and arguments and executing a multidimensional pattern match against the MBean provided &lt;a href="http://docs.oracle.com/javase/1.5.0/docs/api/javax/management/MBeanOperationInfo.html" target="_blank"&gt;MBeanOperationInfo&lt;/a&gt;s. &lt;br /&gt;
&lt;br /&gt;
Gmx is also integrated with the Java Attach API so another way of acquiring a &lt;b&gt;Gmx&lt;/b&gt; instance is to specify the PID of the JVM you want to attach to. The following example illustrates a script that discovers all (Attach API compatible) JVMs on the local machine and then prints the MBeanServerID attribute for each from the &lt;a href="http://docs.oracle.com/javase/1.5.0/docs/api/javax/management/MBeanServerDelegate.html" target="_blank"&gt;MBeanServerDelegate &lt;/a&gt;MBean.&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1571900.js"&gt;
&lt;/script&gt;
&lt;br /&gt;
The output of this script is:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;b&gt;helios104_1324051453215&lt;br /&gt;helios104_1325860886519&lt;br /&gt;helios104_1325876067431&lt;br /&gt;helios104_1325782180150&lt;/b&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;/blockquote&gt;
Not &lt;i&gt;super&lt;/i&gt; interesting, but I think the brevity is great. 
&lt;br /&gt;
This last example demonstrates some of the powerful optimizations of the Groovy remoting implemented by Gmx. To contrive an example, consider determining the total number of thread blocks across all threads in a JVM. Rather than retrieving every &lt;a href="http://docs.oracle.com/javase/6/docs/api/java/lang/management/ThreadInfo.html" target="_blank"&gt;ThreadInfo&lt;/a&gt; from the &lt;a href="http://docs.oracle.com/javase/6/docs/api/java/lang/management/ThreadMXBean.html" target="_blank"&gt;ThreadMXBean&lt;/a&gt; and computing the total locally, I install the Gmx remoting on the remote MBeanServer and pass a script to perform the computation on the remote JVM and then return the result.
&lt;br /&gt;
&lt;script src="https://gist.github.com/1572517.js"&gt;
&lt;/script&gt;
&lt;br /&gt;
&amp;nbsp;The raw script passing is a bit awkward,&lt;strike&gt; and I'm working on implementing seamless remote closure invocation (See &lt;a href="https://github.com/nickman/GroovyMX/issues/15" target="_blank"&gt;Issue #15&lt;/a&gt;).&lt;/strike&gt;&amp;nbsp; and native closures are now supported. See &lt;a href="http://seeallhearall.blogspot.com/2012/01/remoting-groovy-with-generated-closures.html" target="_blank"&gt;here &lt;/a&gt;and &lt;a href="http://seeallhearall.blogspot.com/2012/01/groovymx-new-remote-jvm-test-cases.html" target="_blank"&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
There are several more features which are complete, defective, in the roadmap/documentation or just in my imagination, but if you are interested, please check out the Gmx GitHub Site's &lt;a href="https://github.com/nickman/GroovyMX" target="_blank"&gt;Source Code&lt;/a&gt;, &lt;a href="https://github.com/nickman/GroovyMX/issues" target="_blank"&gt;Issues &lt;/a&gt;and &lt;a href="https://github.com/nickman/GroovyMX/wiki/_pages" target="_blank"&gt;Wiki&lt;/a&gt;. I just started this recently so its not ready for a release, but you can download a snapshot from my Cloudbees snapshot repository.&lt;br /&gt;
&lt;br /&gt;
Snapshots:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://repository-helios.forge.cloudbees.com/snapshot/org/helios/gmx/1.0-SNAPSHOT/gmx-1.0-SNAPSHOT.jar"&gt; Standalone&lt;/a&gt; (no dependencies)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://repository-helios.forge.cloudbees.com/snapshot/org/helios/gmx/1.0-SNAPSHOT/gmx-1.0-SNAPSHOT-jar-with-dependencies.jar"&gt;Full &lt;/a&gt;(includes dependencies)&lt;/li&gt;
&lt;/ul&gt;
The dependencies can be viewed in the Gmx &lt;a href="https://github.com/nickman/GroovyMX/blob/master/gmx/pom.xml" target="_blank"&gt;Maven Pom&lt;/a&gt;. &lt;br /&gt;
&lt;br /&gt;
There are some additional examples in the project unit tests:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt; &lt;a href="https://github.com/nickman/GroovyMX/blob/master/gmx/src/test/java/org/helios/gmx/GmxTestCase.java" target="_blank"&gt;Java&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/nickman/GroovyMX/blob/master/gmx/src/test/groovy/core/GmxTestCase.groovy" target="_blank"&gt;Groovy&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
If you have any feedback, please drop a comment on this blog.&lt;br /&gt;
&lt;br /&gt;
Cheers.&lt;br /&gt;
&lt;ul&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11251261-1784822801782775576?l=seeallhearall.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/lxpdT/~4/SV0eEqR10G0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://seeallhearall.blogspot.com/feeds/1784822801782775576/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=11251261&amp;postID=1784822801782775576&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/11251261/posts/default/1784822801782775576?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/11251261/posts/default/1784822801782775576?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/lxpdT/~3/SV0eEqR10G0/groovymx-groovy-jmx-client.html" title="GroovyMX: A Groovy JMX Client" /><author><name>nickman</name><uri>http://www.blogger.com/profile/09238427833396441114</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://seeallhearall.blogspot.com/2012/01/groovymx-groovy-jmx-client.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEIBSXc_cCp7ImA9WhdQFE4.&quot;"><id>tag:blogger.com,1999:blog-11251261.post-1851494756990248292</id><published>2011-08-15T14:22:00.000-04:00</published><updated>2011-08-15T14:22:38.948-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-15T14:22:38.948-04:00</app:edited><title>Java 7 for .Net - IKVM Not Slouching</title><content type="html">I've always been impressed with &lt;a href="http://www.ikvm.net/"&gt;IKVM&lt;/a&gt;, a compiler that converts Java Byte Code into .NET CLR byte code in the form of assemblies. It is astonishing how much core (and a lot of non-core) Java re-compiles into .Net with relatively little effort.&lt;br /&gt;
&lt;br /&gt;
Shortly after the release of Java 7, the IKVM team has already released a &lt;a href="http://weblog.ikvm.net/PermaLink.aspx?guid=897f3cb2-9c9b-40c9-a9d7-c72a1a6d44a7"&gt;development snapshot&lt;/a&gt; of IKVM supporting it. &lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;i&gt;&lt;b&gt;After a massive amount of work, we finally have a new development  snapshot based on OpenJDK 7 b147. There is still a lot of work to do to  implement all the new functionality, but at least all the OpenJDK code  has now been integrated.&lt;/b&gt;&lt;/i&gt;&lt;/blockquote&gt;Nice work guys.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11251261-1851494756990248292?l=seeallhearall.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/lxpdT/~4/4QW6giPOYCU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://seeallhearall.blogspot.com/feeds/1851494756990248292/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=11251261&amp;postID=1851494756990248292&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/11251261/posts/default/1851494756990248292?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/11251261/posts/default/1851494756990248292?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/lxpdT/~3/4QW6giPOYCU/java-7-for-net-ikvm-not-slouching.html" title="Java 7 for .Net - IKVM Not Slouching" /><author><name>nickman</name><uri>http://www.blogger.com/profile/09238427833396441114</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://seeallhearall.blogspot.com/2011/08/java-7-for-net-ikvm-not-slouching.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak4CQHk7fyp7ImA9WhdTFEQ.&quot;"><id>tag:blogger.com,1999:blog-11251261.post-5105547925899275605</id><published>2011-07-12T15:29:00.000-04:00</published><updated>2011-07-12T15:29:21.707-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-07-12T15:29:21.707-04:00</app:edited><title>JBoss AS7 Wicked Fast Startup, But Has Serious Deal Breaker ?</title><content type="html">The new &lt;a href="http://www.jboss.org/as7.html"&gt;JBoss AS7 Release&lt;/a&gt; definitely has a blazingly fast startup. When I ran it for the first time: &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;14:26:24,770 INFO&amp;nbsp; [org.jboss.as] (Controller Boot Thread) JBoss AS 7.0.0.Final "Lightning" started in &lt;span style="color: red;"&gt;1489ms&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
And not for nothing, it has a wicked fast shutdown too !&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;b&gt;14:39:03,703 INFO&amp;nbsp; [org.jboss.as] JBoss AS 7.0.0.Final "Lightning" stopped in 7ms&lt;/b&gt;&lt;/div&gt;&lt;br /&gt;
A colleague commented:&lt;br /&gt;
&lt;br /&gt;
&lt;!--[if gte mso 9]&gt;&lt;xml&gt;  &lt;w:WordDocument&gt;   &lt;w:View&gt;Normal&lt;/w:View&gt;   &lt;w:Zoom&gt;0&lt;/w:Zoom&gt;   &lt;w:TrackMoves/&gt;   &lt;w:TrackFormatting/&gt;   &lt;w:PunctuationKerning/&gt;   &lt;w:ValidateAgainstSchemas/&gt;   &lt;w:SaveIfXMLInvalid&gt;false&lt;/w:SaveIfXMLInvalid&gt;   &lt;w:IgnoreMixedContent&gt;false&lt;/w:IgnoreMixedContent&gt;   &lt;w:AlwaysShowPlaceholderText&gt;false&lt;/w:AlwaysShowPlaceholderText&gt;   &lt;w:DoNotPromoteQF/&gt;   &lt;w:LidThemeOther&gt;EN-US&lt;/w:LidThemeOther&gt;   &lt;w:LidThemeAsian&gt;X-NONE&lt;/w:LidThemeAsian&gt;   &lt;w:LidThemeComplexScript&gt;X-NONE&lt;/w:LidThemeComplexScript&gt;   &lt;w:Compatibility&gt;    &lt;w:BreakWrappedTables/&gt;    &lt;w:SnapToGridInCell/&gt;    &lt;w:WrapTextWithPunct/&gt;    &lt;w:UseAsianBreakRules/&gt;    &lt;w:DontGrowAutofit/&gt;    &lt;w:SplitPgBreakAndParaMark/&gt;    &lt;w:DontVertAlignCellWithSp/&gt;    &lt;w:DontBreakConstrainedForcedTables/&gt;    &lt;w:DontVertAlignInTxbx/&gt;    &lt;w:Word11KerningPairs/&gt;    &lt;w:CachedColBalance/&gt;   &lt;/w:Compatibility&gt;   &lt;w:BrowserLevel&gt;MicrosoftInternetExplorer4&lt;/w:BrowserLevel&gt;   &lt;m:mathPr&gt;    &lt;m:mathFont m:val="Cambria Math"/&gt;    &lt;m:brkBin m:val="before"/&gt;    &lt;m:brkBinSub m:val="&amp;#45;-"/&gt;    &lt;m:smallFrac m:val="off"/&gt;    &lt;m:dispDef/&gt;    &lt;m:lMargin m:val="0"/&gt;    &lt;m:rMargin m:val="0"/&gt;    &lt;m:defJc m:val="centerGroup"/&gt;    &lt;m:wrapIndent m:val="1440"/&gt;    &lt;m:intLim m:val="subSup"/&gt;    &lt;m:naryLim m:val="undOvr"/&gt;   &lt;/m:mathPr&gt;&lt;/w:WordDocument&gt; &lt;/xml&gt;&lt;![endif]--&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;  &lt;w:LatentStyles DefLockedState="false" DefUnhideWhenUsed="true"
  DefSemiHidden="true" DefQFormat="false" DefPriority="99"
  LatentStyleCount="267"&gt;   &lt;w:LsdException Locked="false" Priority="0" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Normal"/&gt;   &lt;w:LsdException Locked="false" Priority="9" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="heading 1"/&gt;   &lt;w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 2"/&gt;   &lt;w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 3"/&gt;   &lt;w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 4"/&gt;   &lt;w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 5"/&gt;   &lt;w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 6"/&gt;   &lt;w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 7"/&gt;   &lt;w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 8"/&gt;   &lt;w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 9"/&gt;   &lt;w:LsdException Locked="false" Priority="39" Name="toc 1"/&gt;   &lt;w:LsdException Locked="false" Priority="39" Name="toc 2"/&gt;   &lt;w:LsdException Locked="false" Priority="39" Name="toc 3"/&gt;   &lt;w:LsdException Locked="false" Priority="39" Name="toc 4"/&gt;   &lt;w:LsdException Locked="false" Priority="39" Name="toc 5"/&gt;   &lt;w:LsdException Locked="false" Priority="39" Name="toc 6"/&gt;   &lt;w:LsdException Locked="false" Priority="39" Name="toc 7"/&gt;   &lt;w:LsdException Locked="false" Priority="39" Name="toc 8"/&gt;   &lt;w:LsdException Locked="false" Priority="39" Name="toc 9"/&gt;   &lt;w:LsdException Locked="false" Priority="35" QFormat="true" Name="caption"/&gt;   &lt;w:LsdException Locked="false" Priority="10" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Title"/&gt;   &lt;w:LsdException Locked="false" Priority="1" Name="Default Paragraph Font"/&gt;   &lt;w:LsdException Locked="false" Priority="11" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Subtitle"/&gt;   &lt;w:LsdException Locked="false" Priority="22" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Strong"/&gt;   &lt;w:LsdException Locked="false" Priority="20" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Emphasis"/&gt;   &lt;w:LsdException Locked="false" Priority="59" SemiHidden="false"
   UnhideWhenUsed="false" Name="Table Grid"/&gt;   &lt;w:LsdException Locked="false" UnhideWhenUsed="false" Name="Placeholder Text"/&gt;   &lt;w:LsdException Locked="false" Priority="1" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="No Spacing"/&gt;   &lt;w:LsdException Locked="false" Priority="60" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Shading"/&gt;   &lt;w:LsdException Locked="false" Priority="61" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light List"/&gt;   &lt;w:LsdException Locked="false" Priority="62" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Grid"/&gt;   &lt;w:LsdException Locked="false" Priority="63" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 1"/&gt;   &lt;w:LsdException Locked="false" Priority="64" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 2"/&gt;   &lt;w:LsdException Locked="false" Priority="65" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 1"/&gt;   &lt;w:LsdException Locked="false" Priority="66" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 2"/&gt;   &lt;w:LsdException Locked="false" Priority="67" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 1"/&gt;   &lt;w:LsdException Locked="false" Priority="68" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 2"/&gt;   &lt;w:LsdException Locked="false" Priority="69" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 3"/&gt;   &lt;w:LsdException Locked="false" Priority="70" SemiHidden="false"
   UnhideWhenUsed="false" Name="Dark List"/&gt;   &lt;w:LsdException Locked="false" Priority="71" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Shading"/&gt;   &lt;w:LsdException Locked="false" Priority="72" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful List"/&gt;   &lt;w:LsdException Locked="false" Priority="73" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Grid"/&gt;   &lt;w:LsdException Locked="false" Priority="60" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Shading Accent 1"/&gt;   &lt;w:LsdException Locked="false" Priority="61" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light List Accent 1"/&gt;   &lt;w:LsdException Locked="false" Priority="62" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Grid Accent 1"/&gt;   &lt;w:LsdException Locked="false" Priority="63" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 1 Accent 1"/&gt;   &lt;w:LsdException Locked="false" Priority="64" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 2 Accent 1"/&gt;   &lt;w:LsdException Locked="false" Priority="65" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 1 Accent 1"/&gt;   &lt;w:LsdException Locked="false" UnhideWhenUsed="false" Name="Revision"/&gt;   &lt;w:LsdException Locked="false" Priority="34" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="List Paragraph"/&gt;   &lt;w:LsdException Locked="false" Priority="29" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Quote"/&gt;   &lt;w:LsdException Locked="false" Priority="30" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Intense Quote"/&gt;   &lt;w:LsdException Locked="false" Priority="66" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 2 Accent 1"/&gt;   &lt;w:LsdException Locked="false" Priority="67" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 1 Accent 1"/&gt;   &lt;w:LsdException Locked="false" Priority="68" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 2 Accent 1"/&gt;   &lt;w:LsdException Locked="false" Priority="69" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 3 Accent 1"/&gt;   &lt;w:LsdException Locked="false" Priority="70" SemiHidden="false"
   UnhideWhenUsed="false" Name="Dark List Accent 1"/&gt;   &lt;w:LsdException Locked="false" Priority="71" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Shading Accent 1"/&gt;   &lt;w:LsdException Locked="false" Priority="72" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful List Accent 1"/&gt;   &lt;w:LsdException Locked="false" Priority="73" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Grid Accent 1"/&gt;   &lt;w:LsdException Locked="false" Priority="60" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Shading Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="61" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light List Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="62" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Grid Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="63" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 1 Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="64" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 2 Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="65" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 1 Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="66" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 2 Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="67" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 1 Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="68" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 2 Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="69" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 3 Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="70" SemiHidden="false"
   UnhideWhenUsed="false" Name="Dark List Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="71" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Shading Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="72" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful List Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="73" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Grid Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="60" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Shading Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="61" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light List Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="62" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Grid Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="63" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 1 Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="64" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 2 Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="65" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 1 Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="66" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 2 Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="67" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 1 Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="68" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 2 Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="69" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 3 Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="70" SemiHidden="false"
   UnhideWhenUsed="false" Name="Dark List Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="71" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Shading Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="72" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful List Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="73" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Grid Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="60" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Shading Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="61" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light List Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="62" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Grid Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="63" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 1 Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="64" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 2 Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="65" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 1 Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="66" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 2 Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="67" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 1 Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="68" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 2 Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="69" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 3 Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="70" SemiHidden="false"
   UnhideWhenUsed="false" Name="Dark List Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="71" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Shading Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="72" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful List Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="73" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Grid Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="60" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Shading Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="61" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light List Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="62" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Grid Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="63" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 1 Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="64" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 2 Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="65" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 1 Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="66" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 2 Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="67" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 1 Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="68" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 2 Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="69" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 3 Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="70" SemiHidden="false"
   UnhideWhenUsed="false" Name="Dark List Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="71" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Shading Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="72" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful List Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="73" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Grid Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="60" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Shading Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="61" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light List Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="62" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Grid Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="63" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 1 Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="64" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 2 Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="65" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 1 Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="66" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 2 Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="67" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 1 Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="68" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 2 Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="69" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 3 Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="70" SemiHidden="false"
   UnhideWhenUsed="false" Name="Dark List Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="71" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Shading Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="72" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful List Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="73" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Grid Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="19" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Subtle Emphasis"/&gt;   &lt;w:LsdException Locked="false" Priority="21" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Intense Emphasis"/&gt;   &lt;w:LsdException Locked="false" Priority="31" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Subtle Reference"/&gt;   &lt;w:LsdException Locked="false" Priority="32" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Intense Reference"/&gt;   &lt;w:LsdException Locked="false" Priority="33" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Book Title"/&gt;   &lt;w:LsdException Locked="false" Priority="37" Name="Bibliography"/&gt;   &lt;w:LsdException Locked="false" Priority="39" QFormat="true" Name="TOC Heading"/&gt;  &lt;/w:LatentStyles&gt; &lt;/xml&gt;&lt;![endif]--&gt;&lt;!--[if gte mso 10]&gt; &lt;style&gt;
 /* Style Definitions */
 table.MsoNormalTable
 {mso-style-name:"Table Normal";
 mso-tstyle-rowband-size:0;
 mso-tstyle-colband-size:0;
 mso-style-noshow:yes;
 mso-style-priority:99;
 mso-style-qformat:yes;
 mso-style-parent:"";
 mso-padding-alt:0in 5.4pt 0in 5.4pt;
 mso-para-margin:0in;
 mso-para-margin-bottom:.0001pt;
 mso-pagination:widow-orphan;
 font-size:11.0pt;
 font-family:"Calibri","sans-serif";
 mso-ascii-font-family:Calibri;
 mso-ascii-theme-font:minor-latin;
 mso-fareast-font-family:"Times New Roman";
 mso-fareast-theme-font:minor-fareast;
 mso-hansi-font-family:Calibri;
 mso-hansi-theme-font:minor-latin;
 mso-bidi-font-family:"Times New Roman";
 mso-bidi-theme-font:minor-bidi;}
&lt;/style&gt; &lt;![endif]--&gt;  &lt;br /&gt;
&lt;div class="MsoNormal"&gt;&lt;i&gt;&lt;span style="mso-fareast-font-family: &amp;quot;Times New Roman&amp;quot;;"&gt;"Yes, I've already been heckling the Tomcat guys, since they staked all their arguments on startup times. :)"&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span&gt;So that's all very exciting (I mean the whole AS7) but I have to say that the one deal breaker is the absence of &lt;b&gt;JMX-Console&lt;/b&gt;. (Note: I might be wrong here, but it sure doesn't look like its in there) For those not in the know, this is a very spartan, but genius and &lt;/span&gt;&lt;i&gt;&lt;span&gt;super functional&lt;/span&gt;&lt;/i&gt;&lt;span&gt; admin and development console for JBoss AS. I always loved the darn thing. It cuts straight to the chase giving you the info and operation invocation links you need without any of the fluff other application servers seem to insist on putting in.&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span&gt;The &lt;b&gt;JNDIViewer&lt;/b&gt; alone was incredibly useful and if more widely used would preempt a bunch a problems because developers can actually &lt;i&gt;see what's bound in JNDI&lt;/i&gt; !&amp;nbsp; What a concept ! &lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span&gt;So has JMX been eschewed completely ? I seriously doubt it. Uh... wait...&amp;nbsp; what is that....&amp;nbsp; &lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span&gt;I mean, I seriously hope not, that's what it is.&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span&gt;At any rate, it seems the platform MBeanServer has a few bits and pieces registered in it, and I suspect (or is it hope ?)&amp;nbsp; there is more that is optionally configurable.&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-fgz8RzKqLWA/ThydqfRN2vI/AAAAAAAABps/43DULNiuVOY/s1600/jbossjmx7.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-fgz8RzKqLWA/ThydqfRN2vI/AAAAAAAABps/43DULNiuVOY/s1600/jbossjmx7.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11251261-5105547925899275605?l=seeallhearall.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/lxpdT/~4/VTkn-1XhjOw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://seeallhearall.blogspot.com/feeds/5105547925899275605/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=11251261&amp;postID=5105547925899275605&amp;isPopup=true" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/11251261/posts/default/5105547925899275605?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/11251261/posts/default/5105547925899275605?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/lxpdT/~3/VTkn-1XhjOw/jboss-as7-wicked-fast-startup-but-has.html" title="JBoss AS7 Wicked Fast Startup, But Has Serious Deal Breaker ?" /><author><name>nickman</name><uri>http://www.blogger.com/profile/09238427833396441114</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-fgz8RzKqLWA/ThydqfRN2vI/AAAAAAAABps/43DULNiuVOY/s72-c/jbossjmx7.png" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://seeallhearall.blogspot.com/2011/07/jboss-as7-wicked-fast-startup-but-has.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE4NSXk8eSp7ImA9WhZWGE4.&quot;"><id>tag:blogger.com,1999:blog-11251261.post-6310792368497110673</id><published>2011-05-19T16:29:00.000-04:00</published><updated>2011-05-19T16:29:58.771-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-19T16:29:58.771-04:00</app:edited><title>Graphite Server Virtual Box Appliance</title><content type="html">I have made some additional improvements to my automated &lt;a href="http://graphite.wikidot.com/start"&gt;Graphite&lt;/a&gt; installer. Last time I &lt;a href="http://seeallhearall.blogspot.com/2011/05/graphite-great-app-laborious-install.html"&gt;posted&lt;/a&gt; the install script, it was admittedly&amp;nbsp; missing several things, but the new one goes from &lt;b style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;./install.sh&lt;/b&gt; to the Graphite web console in one go.&lt;br /&gt;
&lt;br /&gt;
At any rate, the new installer has significantly eased the process of creating VM appliances for Graphite which I have made available for download if you are interested in taking Graphite for a test drive, or you need a pre-built development environment. Since the VMs, as configured, are resource limited, I am not sure if they are suitable for any production use, but if you bump up the CPUs, the memory and modify the setup to use some fast native (or SAN) disks for the Whisper storage, I imagine they would be pretty decent.&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://heliosapm.com/helios/graphite/Graphite32.0.9.8.tar"&gt;Ubuntu Desktop 10.10 32 bit, Graphite 0.9.8&lt;/a&gt; &lt;span style="font-size: xx-small;"&gt;&lt;i&gt;(928,977,606 bytes)&lt;/i&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://heliosapm.com/helios/graphite/Graphite64.0.9.8.tar"&gt;Ubuntu Desktop 10.10 64 bit, Graphite 0.9.8&lt;/a&gt; &lt;span style="font-size: xx-small;"&gt;&lt;i&gt;(869,840,705 bytes)&lt;/i&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;Here's some details you should know: &lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Created with Virtual Box 4.0.6&lt;/li&gt;
&lt;li&gt;The OS user is &lt;b&gt;helios&lt;/b&gt;. The password is &lt;b&gt;helios&lt;/b&gt;.&lt;/li&gt;
&lt;li&gt;The Graphite admin user is &lt;b&gt;helios&lt;/b&gt;. The password is &lt;b&gt;helios&lt;/b&gt;. Now that I think about it, the user's email address is &lt;b&gt;graphite@heliosdev.org&lt;/b&gt; so you might want to review my summary below on how you can change this.&lt;/li&gt;
&lt;li&gt;Once you start the VM, the Graphite Console is available at &lt;i&gt;&lt;b&gt;http://localhost&lt;/b&gt;&lt;/i&gt; and remotely at whatever IP you designate. (Out of the box, the NIC is configured for bridging).&lt;/li&gt;
&lt;li&gt;The Graphite install script and supporting files are in &lt;b&gt;/home/helios/graphite&lt;/b&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;b&gt;carbon&lt;/b&gt; listener is started by &lt;i&gt;&lt;b&gt;/etc/init.d/carbon&lt;/b&gt;&lt;/i&gt; which runs the process as user &lt;b&gt;www-data&lt;/b&gt; and I recommend you stick to using it. If you start carbon directly with &lt;b&gt;sudo&lt;/b&gt;, the process will run as root and may create files that are subsequently not readable by &lt;b&gt;www-data&lt;/b&gt;.&lt;/li&gt;
&lt;li&gt;The carbon [linetext] listener listens on port 2003.&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;u&gt;&lt;b&gt;Changing the Graphite Admin User&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
&lt;br /&gt;
The user accounts are stored in a &lt;b&gt;sqlite&lt;/b&gt; database/file &lt;b&gt;/opt/graphite/storage/graphite.db&lt;/b&gt;,&amp;nbsp; specifically in a table called &lt;b&gt;auth_user&lt;/b&gt;. You can run the &lt;b&gt;sqlitebrowser&lt;/b&gt; GUI tool and edit the file directly&amp;nbsp; (using sudo). Or, you can delete the file (using sudo) and re-initialize as follows:&amp;nbsp; (using sudo)&lt;code&gt;&amp;nbsp;&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;&lt;code&gt;cd /opt/graphite/webapp/graphite&lt;/code&gt;&lt;code&gt;&amp;nbsp;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sudo python manage.py syncdb&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;This will recreate the database and prompt you to create a new admin user.&lt;br /&gt;
&lt;br /&gt;
And I thank &lt;a href="http://www.hostmonster.com/"&gt;HostMonster&lt;/a&gt; for their nicely priced hosting that affords me the ability to serve these files.&lt;br /&gt;
&lt;br /&gt;
Next post perhaps I will explain:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Why did I build this appliance using Desktop instead of Server ?&lt;/li&gt;
&lt;li&gt;Where is the VMware version of this appliance ?&lt;/li&gt;
&lt;li&gt;Where and when is the OpenTrace client for passing collected JMX metrics to Graphite ?&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11251261-6310792368497110673?l=seeallhearall.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/lxpdT/~4/ssCjD6U1SJw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://seeallhearall.blogspot.com/feeds/6310792368497110673/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=11251261&amp;postID=6310792368497110673&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/11251261/posts/default/6310792368497110673?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/11251261/posts/default/6310792368497110673?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/lxpdT/~3/ssCjD6U1SJw/graphite-server-virtual-box-appliance.html" title="Graphite Server Virtual Box Appliance" /><author><name>nickman</name><uri>http://www.blogger.com/profile/09238427833396441114</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://seeallhearall.blogspot.com/2011/05/graphite-server-virtual-box-appliance.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUEDQ3s7cCp7ImA9WhZWGEQ.&quot;"><id>tag:blogger.com,1999:blog-11251261.post-4079202236410744656</id><published>2011-05-14T16:22:00.002-04:00</published><updated>2011-05-20T09:21:12.508-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-20T09:21:12.508-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java Python Graphite JMX" /><title>Graphite - Great App, Laborious Install (Until now ?)</title><content type="html">&lt;a href="http://graphite.wikidot.com/start"&gt;Graphite&lt;/a&gt; is a great APM supporting tool. It is basically (and broadly speaking)&amp;nbsp; a python based server (Linux only AFAICT) with 3 components:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;&lt;a href="http://graphite.wikidot.com/whisper"&gt;Whisper&lt;/a&gt;: An RRD like database which is quite fast.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://graphite.wikidot.com/carbon"&gt;Carbon&lt;/a&gt;: A high performance cache and network listener that listens for submitted data and stashes it in Whisper.&lt;/li&gt;
&lt;li&gt;Graphite: A web application that allows you to visualize and report data historically or in real time.&lt;/li&gt;
&lt;/ol&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-Vugzj5U06KU/Tc7muUhNQOI/AAAAAAAABoo/aKbIEaIjcmE/s1600/Graphite.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="228" src="http://2.bp.blogspot.com/-Vugzj5U06KU/Tc7muUhNQOI/AAAAAAAABoo/aKbIEaIjcmE/s400/Graphite.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-ftQEgwhj_Mo/Tc7doLnWmTI/AAAAAAAABog/BnND6MlG4jE/s1600/Graphite.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;br /&gt;
&lt;/a&gt;&lt;/div&gt;The data submission protocol and data format is very simple so wherever you collect performance data from, it's easy to deliver it to Graphite. You can optionally submit data through RabbitMQ but I have observed that the basic Text over socket is better performing since you can batch up many metrics in one go,while the Rabbit submission is one metric per message.&lt;br /&gt;
&lt;br /&gt;
This python language is pretty interesting. Not that I am trying to learn it, but perusing the &lt;b&gt;.py&lt;/b&gt; files in the Graphite distro is edifying and for a java person, the general working bits-and-pieces of python is not hard to understand. (Now writing something useful.... different story).&lt;br /&gt;
&lt;br /&gt;
After the umpteenth DZone posting from some code rock-star cum superhero admonishing us all to learn multiple languages, my feeling of inadequacy led me to consider delving into python. Sadly, I chose Erlang, having heard that women in bars are the most impressed with that. I'll save that story for another day, but suffice it to say that after I recovered from that blazing flame-out, I picked Groovy. Yes, it is still Java based, but the rock-stars let it slide because it has closures and befriends both sides of the &lt;i&gt;&lt;b&gt;statically-typed-versus-dynamically-typed&lt;/b&gt;&lt;/i&gt; interstellar war. Apparently my prior list up until Groovy which was Java 1.3, Java 1.4, Java 1.5, Java 1.6 and bash (for a total of 5) was not passing muster.&lt;br /&gt;
&lt;br /&gt;
I have been adapting OpenTrace to optionally send collected metrics to Graphite. Naturally, since I am A.R. about low level metrics, I publish the tracer's metrics through JMX.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-TOveqJCfoAo/Tc7fz31dQLI/AAAAAAAABok/qRJTBIzQtf0/s1600/GraphiteJMX.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="283" src="http://4.bp.blogspot.com/-TOveqJCfoAo/Tc7fz31dQLI/AAAAAAAABok/qRJTBIzQtf0/s400/GraphiteJMX.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
The&amp;nbsp; idea is the tracer accumulates metrics until &lt;i&gt;&lt;b&gt;t &lt;/b&gt;&lt;/i&gt;time elapses, or &lt;i&gt;&lt;b&gt;n&lt;/b&gt;&lt;/i&gt; metrics accumulate, and then the buffer is flushed up to Carbon. So can you see the metrics in real time ? Well yes. (Nice of you to ask). The Graphite Dev team explains:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;h1 id="toc2"&gt;&lt;i&gt;&lt;span style="font-size: large;"&gt;How are Graphite graphs always real-time, even when carbon hasn't had time to write it's cached data to disk yet?&lt;/span&gt;&lt;/i&gt;&lt;/h1&gt;&lt;i&gt;Upon receiving a rendering request, the Graphite webapp  simultaneously retrieves data for the requested metrics from the disk  and from carbon's cache via a simple cache query socket that  carbon-cache provides. Graphite then combines these two sources of data  points into a single series, which is then rendered. This ensures that  graphs are always real-time, even when the data hasn't been written to  disk yet.&lt;/i&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I have been working on an Ubuntu 10.10 VirtualBox appliance that I can distribute because the installation of Graphite is a bit laborious, and each time I do it, I always forget one thing or another. The &lt;a href="http://graphite.wikidot.com/installation"&gt;installation documentation&lt;/a&gt; is decent, but there's a lot of moving parts here, and many of them differ by Linux distro, so I can't really fault the Graphite dev team in this regard. I saw something somewhere about an effort to put together Linux packages, but I can't find reference to it now.&lt;br /&gt;
&lt;br /&gt;
At any rate, after the 23rd consecutive time of installing Graphite (and all the requisite packages) onto my Ubuntu guest, I think I finally nailed down a script that does most of the hard work, and it is here for your productivity and reading pleasure:&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;&lt;b&gt;Updated: Friday May 20, 2011&lt;/b&gt;&lt;/u&gt; &lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/982866.js?file=install.sh"&gt;
&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11251261-4079202236410744656?l=seeallhearall.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/lxpdT/~4/9yg9VKHOuvU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://seeallhearall.blogspot.com/feeds/4079202236410744656/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=11251261&amp;postID=4079202236410744656&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/11251261/posts/default/4079202236410744656?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/11251261/posts/default/4079202236410744656?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/lxpdT/~3/9yg9VKHOuvU/graphite-great-app-laborious-install.html" title="Graphite - Great App, Laborious Install (Until now ?)" /><author><name>nickman</name><uri>http://www.blogger.com/profile/09238427833396441114</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-Vugzj5U06KU/Tc7muUhNQOI/AAAAAAAABoo/aKbIEaIjcmE/s72-c/Graphite.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://seeallhearall.blogspot.com/2011/05/graphite-great-app-laborious-install.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkMAQXw4eip7ImA9WhZXGUs.&quot;"><id>tag:blogger.com,1999:blog-11251261.post-3508839520453739385</id><published>2011-05-09T15:14:00.000-04:00</published><updated>2011-05-09T15:14:00.232-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-09T15:14:00.232-04:00</app:edited><title>Spin vs. Sleep vs. Join</title><content type="html">As I was reading about why &lt;a href="http://esper.codehaus.org/"&gt;Esper &lt;/a&gt;sometimes implements &lt;a href="http://en.wikipedia.org/wiki/Spin_Lock"&gt;Spin Locks&lt;/a&gt; instead of thread suspension, I wondered what the actual benefits were. I put together a quick and very simple test to measure elapsed time and CPU utilization of 3 different suspension operations:&amp;nbsp; (Using java version "1.6.0_21" on Windows 7)&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Spin: Capture &lt;b&gt;until&lt;/b&gt; (the current time plus the suspend time in ms.) and loop until the current time is equal to or greater than &lt;b&gt;until&lt;/b&gt;.&lt;/li&gt;
&lt;li&gt;Sleep: Call &lt;b&gt;Thread.sleep(&lt;i&gt;&lt;suspend in="" ms.="" time=""&gt;&lt;/suspend&gt;&lt;/i&gt;)&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Join:&lt;/b&gt; Call &lt;b&gt;Thread.currentThread().join(&lt;/b&gt;&lt;b&gt;&lt;i&gt;&lt;suspend in="" ms.="" time=""&gt;&lt;/suspend&gt;&lt;/i&gt;&lt;/b&gt;&lt;b&gt;)&lt;/b&gt;.&lt;b&gt;&amp;nbsp;&lt;/b&gt; &lt;/li&gt;
&lt;/ol&gt;This was a single thread, called in main, sleeping for 5 ms. in a loop of&amp;nbsp; 100,000. As it turns out, &lt;b&gt;&lt;i&gt;Spin&lt;/i&gt;&lt;/b&gt; is the absolute &lt;i&gt;most&lt;/i&gt; precise of the three, running with zero loss of precision, but at a cost of 499,905 ms. of CPU time.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Sleep&lt;/b&gt;&lt;/i&gt; lost the most precision with 1,358 ms. worth of latency and a cost of 31 ms. of CPU time.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Join&lt;/b&gt;&lt;/i&gt; seems to be the best compromise with zero CPU utilization and only 7 ms. loss of precision.&lt;br /&gt;
&lt;br /&gt;
So the moral of the story, it seems to me, is to always use &lt;b&gt;&lt;i&gt;Join&lt;/i&gt;&lt;/b&gt;&lt;i&gt;&lt;b&gt; &lt;/b&gt;&lt;/i&gt;unless you need a hyper-precise wake-up time. Furthermore,&amp;nbsp; it would seem that &lt;i&gt;&lt;b&gt;Sleep&lt;/b&gt;&lt;/i&gt; is the worst way to achieve a suspension with much lower precision than &lt;i&gt;&lt;b&gt;Join&lt;/b&gt;&lt;/i&gt; at an infinitely higher CPU cost.&lt;br /&gt;
&lt;br /&gt;
Output:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;b&gt;SpinLock vs. Sleep vs. Join&lt;br /&gt;
Warming Up....&lt;br /&gt;
Warm Up Complete&lt;br /&gt;
Starting Spin Test&lt;br /&gt;
Spin:&amp;nbsp;&amp;nbsp; 500000/499905204500&lt;br /&gt;
Starting Sleep Test&lt;br /&gt;
Sleep:&amp;nbsp; 501358/31200200&lt;br /&gt;
Starting Join Test&lt;br /&gt;
Join:&amp;nbsp;&amp;nbsp; 500007/0&lt;/b&gt;&lt;/div&gt;&lt;br /&gt;
====&amp;nbsp; Update ==== &lt;br /&gt;
&lt;br /&gt;
Tested the exact same code using java version "1.6.0_24" on Ubuntu 10.10 X64 and the results were a little different. The &lt;i&gt;&lt;b&gt;Spin&lt;/b&gt;&lt;/i&gt; did have some precision loss (but not much). The biggest difference was that &lt;i&gt;&lt;b&gt;Join&lt;/b&gt;&lt;/i&gt; went from zero CPU cost to 3,970 ms cost, making it more expensive than &lt;i&gt;&lt;b&gt;Sleep&lt;/b&gt;&lt;/i&gt; and with slightly less precision. Not sure what to make of that, except that I need to rerun the tests to make sure there is no skew from background processes or something.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;SpinLock vs. Sleep vs. Join&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Warming Up....&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Warm Up Complete&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Starting Spin Test&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Spin:&amp;nbsp;&amp;nbsp; 500034/499590000000&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Starting Sleep Test&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Sleep:&amp;nbsp; 516430/3680000000&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Starting Join Test&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Join:&amp;nbsp;&amp;nbsp; 516650/3970000000&lt;/span&gt;&lt;/b&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11251261-3508839520453739385?l=seeallhearall.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/lxpdT/~4/CnmHWSFxKTc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://seeallhearall.blogspot.com/feeds/3508839520453739385/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=11251261&amp;postID=3508839520453739385&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/11251261/posts/default/3508839520453739385?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/11251261/posts/default/3508839520453739385?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/lxpdT/~3/CnmHWSFxKTc/spin-vs-sleep-vs-join.html" title="Spin vs. Sleep vs. Join" /><author><name>nickman</name><uri>http://www.blogger.com/profile/09238427833396441114</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://seeallhearall.blogspot.com/2011/05/spin-vs-sleep-vs-join.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEcDR3o-fip7ImA9WxdbFUk.&quot;"><id>tag:blogger.com,1999:blog-11251261.post-7304382802578994953</id><published>2008-08-11T22:54:00.003-04:00</published><updated>2008-08-12T07:54:36.456-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-08-12T07:54:36.456-04:00</app:edited><title>Java run-time monitoring, Part 3</title><content type="html">&lt;a href="http://www.ibm.com/developerworks/library/j-rtm3/index.html"&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;P&lt;/span&gt;&lt;/span&gt;art 3&lt;/a&gt; is not really about monitoring Java itself, but rather how to monitor other resources using Java, plus how to manage and visualize collected data. There are several examples I would have liked to put in the article, but with the PDF version running at 73 pages, it got a bit too long.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11251261-7304382802578994953?l=seeallhearall.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/lxpdT/~4/462SGC0Z5x4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://seeallhearall.blogspot.com/feeds/7304382802578994953/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=11251261&amp;postID=7304382802578994953&amp;isPopup=true" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/11251261/posts/default/7304382802578994953?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/11251261/posts/default/7304382802578994953?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/lxpdT/~3/462SGC0Z5x4/java-run-time-monitoring-part-3.html" title="Java run-time monitoring, Part 3" /><author><name>nickman</name><uri>http://www.blogger.com/profile/09238427833396441114</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total><feedburner:origLink>http://seeallhearall.blogspot.com/2008/08/java-run-time-monitoring-part-3.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkMGSH87eCp7ImA9WxdUGU4.&quot;"><id>tag:blogger.com,1999:blog-11251261.post-4219610091833269888</id><published>2008-08-05T07:24:00.003-04:00</published><updated>2008-08-05T08:13:49.100-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-08-05T08:13:49.100-04:00</app:edited><title>Postcompilation instrumentation and performance monitoring</title><content type="html">&lt;a href="http://www.ibm.com/developerworks/library/j-rtm2/index.html"&gt;Part 2&lt;/a&gt; of my article series on Java run-time monitoring was published today. Last week I reviewed methods of instrumenting java classes at the source level. While not ideal in light of the ubiquity of AOP techniques to inject instrumentation at runtime, if you have or want to do it, take a page from Log4J's book and make sure that the instrumentation is externally configurable  (i.e. you don't need to re-compile to tweak it). Here's a quick list of features you might look for in your Log4J instrumentation analog:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Verbosity&lt;/span&gt;: Yep, just like Log4J (and many other logging packages) the Level of loggers can be modified at runtime through JMX or simply by placing a watch on the XML configuration file.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Thresholds&lt;/span&gt;: Automatically trace incidents when measurements exceed externally defined thresholds.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Ranges&lt;/span&gt;: Automatically trace counts of measurements that fall into a value window as part of an externally defined and named range. (useful for SLAs where an operation's elapsed time might be classified as GOOD, WARN or CIRITCAL.)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Rollups&lt;/span&gt;: Maintain aggregated performance statistics all the way up a hierarchical tree.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;So in this week's article, I review methods of instrumentation that can be used in the post-compilation phase, or more simply, without futzing with the source code.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Interceptors&lt;/span&gt;: J2EE and a bunch of other [not just] Java frameworks support the ability to inject interceptors into the application without ever touching the source code of your code application classes.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Class Wrapping&lt;/span&gt;: Implement instrumentation in a class wrapper and then wrap your target class. You get the same functionality and instrumentation to boot.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Byte Code Instrumentation&lt;/span&gt;: Inject instrumentation byte code directly into your already compiled classes. This can be done statically (i.e. you end up with the original jar and and instrumented jar) or it can be done dynamically at runtime when the classes are classloaded.&lt;/li&gt;&lt;/ul&gt;An additional approach which I did not really address in the article is the concept of class swapping. For example, if you wanted to know some low down performance and byte volume details of a network service, you could create a new class called &lt;code&gt;com.myco.instrumentation.InstrumentedSocket&lt;/code&gt; which extends &lt;code&gt;java.net.Socket&lt;/code&gt; and adds in some basic instrumentation like counting byte transfer rates. At class load time, you could swap out the implementation of all instances of &lt;code&gt;java.net.Socket&lt;/code&gt; with your instrumented version.&lt;br /&gt;&lt;br /&gt;Hopefully the article is useful to you.&lt;br /&gt;&lt;br /&gt;Cheers.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11251261-4219610091833269888?l=seeallhearall.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/lxpdT/~4/BHl5Lh64v2I" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://seeallhearall.blogspot.com/feeds/4219610091833269888/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=11251261&amp;postID=4219610091833269888&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/11251261/posts/default/4219610091833269888?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/11251261/posts/default/4219610091833269888?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/lxpdT/~3/BHl5Lh64v2I/postcompilation-instrumentation-and.html" title="Postcompilation instrumentation and performance monitoring" /><author><name>nickman</name><uri>http://www.blogger.com/profile/09238427833396441114</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://seeallhearall.blogspot.com/2008/08/postcompilation-instrumentation-and.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEUHQHc8cSp7ImA9WxdUE0Q.&quot;"><id>tag:blogger.com,1999:blog-11251261.post-357135398947440753</id><published>2008-07-30T00:30:00.001-04:00</published><updated>2008-07-30T00:30:31.979-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-07-30T00:30:31.979-04:00</app:edited><title>Java Runtime Monitoring, Part 1</title><content type="html">&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;a href='http://www.ibm.com/developerworks/library/j-rtm1/index.html' target='_blank'&gt;Part 1&lt;/a&gt; of my developerWorks series on application monitoring was published today. My goal was to champion the use of fine grained monitoring of the JVM and application code instrumentation.&lt;br/&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11251261-357135398947440753?l=seeallhearall.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/lxpdT/~4/-0824IuNahc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://seeallhearall.blogspot.com/feeds/357135398947440753/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=11251261&amp;postID=357135398947440753&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/11251261/posts/default/357135398947440753?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/11251261/posts/default/357135398947440753?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/lxpdT/~3/-0824IuNahc/java-runtime-monitoring-part-1_30.html" title="Java Runtime Monitoring, Part 1" /><author><name>nickman</name><uri>http://www.blogger.com/profile/09238427833396441114</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://seeallhearall.blogspot.com/2008/07/java-runtime-monitoring-part-1_30.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkIFR3o-eyp7ImA9WBFVFE4.&quot;"><id>tag:blogger.com,1999:blog-11251261.post-112862492844266830</id><published>2005-10-06T11:51:00.001-04:00</published><updated>2007-04-13T00:28:36.453-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-04-13T00:28:36.453-04:00</app:edited><title>AutoDiscovery - [Trying to] Say No To Static Configuration</title><content type="html">I am always on the lookout for ways to avoid configuration files and the like in favour of dynamic discovery. The JBoss HA-JNDI implementation is a great example where you can specify a set of properties and the ContextFactory will automatically discover a server matching your criteria.&lt;br /&gt;&lt;br /&gt;I recently tired of creating yet another user database with roles, passwords, expiration and all the rest of it, so on a new project we started recently for an internal web application, I decided I was going to use the company's Active Directory server. Seemed like a genius idea. Single sign on for my users and I get to delegate all the afformentioned to a bunch of LDAP servers that someone else maintains.&lt;br /&gt;&lt;br /&gt;Down the road a ways, I started thinking about which of 10 LDAP servers I should use. What if one of them goes down ? What if they change ? What if they add new servers ? It turns out (and perhaps you already knew this) that DNS will help you locate servers by service, not just by name. Sun provides a &lt;a href="http://java.sun.com/j2se/1.4.2/docs/guide/jndi/jndi-dns.html"&gt;DNS Service Provider for JNDI &lt;/a&gt;which makes the process nice-n-easy. I could not get it to work exactly as advertised, but with a bit of jiggery pokery, it did the job admirably. In the example below, you simply pass in a peculiar looking string that specifies the service, protocol and domain you are looking for. In my case that string was &lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;_ldap._tcp.mydomain.com&lt;/span&gt;&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/**&lt;br /&gt;* Returns an array of located hosts for the given service descriptor.&lt;br /&gt;* @param service String&lt;br /&gt;* @return LocatedHost[]&lt;br /&gt;* @throws NamingException&lt;br /&gt;*/&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 128);"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; LocatedHost[] locateHosts(String service) &lt;/span&gt;&lt;span style="color: rgb(0, 0, 128);"&gt;&lt;b&gt;throws&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; NamingException {&lt;br /&gt;   Properties dnsProperties = &lt;/span&gt;&lt;span style="color: rgb(0, 0, 128);"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Properties();&lt;br /&gt;   DirContext ctx = &lt;/span&gt;&lt;span style="color: rgb(0, 0, 128);"&gt;&lt;b&gt;null&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;   ArrayList locatedHosts =  &lt;/span&gt;&lt;span style="color: rgb(0, 0, 128);"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; ArrayList();&lt;br /&gt;   dnsProperties.put(&lt;i&gt;Context&lt;/i&gt;.&lt;i&gt;INITIAL_CONTEXT_FACTORY&lt;/i&gt;,  &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;"com.sun.jndi.dns.DnsContextFactory"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);&lt;br /&gt;   dnsProperties.put(&lt;i&gt;Context&lt;/i&gt;.&lt;i&gt;PROVIDER_URL&lt;/i&gt;, &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;dnsList&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);&lt;br /&gt;   String[] hostAttributes = &lt;/span&gt;&lt;span style="color: rgb(0, 0, 128);"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; String[] {&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;"A"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;};&lt;br /&gt;   LocatedHost locatedHost = &lt;/span&gt;&lt;span style="color: rgb(0, 0, 128);"&gt;&lt;b&gt;null&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;   &lt;/span&gt;&lt;span style="color: rgb(0, 0, 128);"&gt;&lt;b&gt;try&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; {&lt;br /&gt;       ctx = &lt;/span&gt;&lt;span style="color: rgb(0, 0, 128);"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; InitialDirContext(dnsProperties);&lt;br /&gt;       DnsContext dnsContext = (DnsContext)ctx.lookup(service);&lt;br /&gt;       Attributes attrs = dnsContext.getAttributes(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;""&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(0, 0, 128);"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; i = attrs.get(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;"srv"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;).size();&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(0, 0, 128);"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 128);"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; c = &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;0&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;; c &lt; locatedhost =" &lt;span style="&gt; LocatedHost();&lt;br /&gt;           String entry = attrs.get(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;"srv"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;).get(c).toString();&lt;br /&gt;           String parsedEntries[] = entry.split(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;" "&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);&lt;br /&gt;           String hostName = parsedEntries[&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;3&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;];&lt;br /&gt;           &lt;/span&gt;&lt;span style="color: rgb(0, 0, 128);"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; port = &lt;i&gt;Integer&lt;/i&gt;.&lt;i&gt;parseInt&lt;/i&gt;(parsedEntries[&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;2&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;]);&lt;br /&gt;           locatedHost.setHostName(hostName);&lt;br /&gt;           locatedHost.setPort(port);&lt;br /&gt;           Attributes hAttr = ctx.getAttributes(hostName, hostAttributes);&lt;br /&gt;           locatedHost.setHostAddress(hAttr.get(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;"A"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;).get().toString());&lt;br /&gt;           locatedHosts.add(locatedHost);&lt;br /&gt;       }&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(0, 0, 128);"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (LocatedHost[])locatedHosts.toArray(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 128);"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; LocatedHost[locatedHosts.size()]);&lt;br /&gt;&lt;br /&gt;   } &lt;/span&gt;&lt;span style="color: rgb(0, 0, 128);"&gt;&lt;b&gt;catch&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (NamingException ex) {&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(0, 0, 128);"&gt;&lt;b&gt;throw&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; ex;&lt;br /&gt;   } &lt;/span&gt;&lt;span style="color: rgb(0, 0, 128);"&gt;&lt;b&gt;finally&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; {&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(0, 0, 128);"&gt;&lt;b&gt;try&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; { ctx.close(); } &lt;/span&gt;&lt;span style="color: rgb(0, 0, 128);"&gt;&lt;b&gt;catch&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (Exception &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;e&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;) {}&lt;br /&gt;   }&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;A few things to note. This method is part of a class which takes a string of space separated DNS server URLs in the constructor. (Loaded into dnsProperties.) The format of the DNS URL is &lt;span style="font-weight: bold;"&gt;dns://&lt;ip&gt;&lt;/ip&gt;&lt;/span&gt;. So to test on my [non DNS serving] laptop, I passed in &lt;span style="font-weight: bold; color: rgb(0, 153, 0);"&gt;"dns://127.0.0.1 dns://216.254.95.2"&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;What is retuned from the lookup entries is an SRV record which turned out to be returned as a string which looks like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;0 100 389 serverAdc1.mydomain.com&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If I iterate through all returned servers, it turns out we have way more than 10 Active Directory servers. More like 53 of them in my domain, so I get back 53 records which look more or less like the one above. Not sure what the two numbers are, but I think the 100 bit is intended to indicate some sort of preference, but every server has the same values, except the actual server name. The third value is the port, and fourth, obviously, is the server name. There is more detail on this in the &lt;a href="http://www.faqs.org/ftp/pub/internet-drafts/draft-ietf-ldapext-locate-08.txt"&gt;internet draft&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Last problem: The list returned is in no particular order, so the first server returned is as likely to be in California than in New Jersey where I am. This is sort of mesmerizing in a &lt;span style="font-style: italic;"&gt;distributed network transparency and location independence&lt;/span&gt; sort of way, but I quickly reaslized that actual authentication calls take significantly longer if the server is far away. I am still researching this issue, but it seems that there is no standard as to the sequence in which these records are returned. Accordingly, I also implemented a slightly less performant version of the code above that actually attempts an anonymous connection against each server as it is discovered. The elapsed time for the connection is measured, and the returned array is then sorted in ascending order of elpased time. Works great, but I would only run it once in a while......&lt;br /&gt;&lt;br /&gt;My most recent exploration on this general subject has been &lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;Service Location Protocol&lt;/span&gt;. &lt;/span&gt;It really seems to fit the bill and should allow me to define custom services with all sorts of additional properties and then be able to automatically discover them. For example, if I want to discover the location of &lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;an  HTTP Custom Service  Invocation Client for Milkshake Delivery&lt;/span&gt;&lt;/span&gt; , the SLP server should be able to tell me where it is, provided that said service registered itself with the SLP server when it started.&lt;br /&gt;&lt;br /&gt;All my SuSE Linux servers had SLP installed by default. However, the only Java API I have found is from &lt;a href="http://www.openslp.org/"&gt;OpenSLP&lt;/a&gt; and I cannot get it to work at all. I can use the &lt;span style="font-weight: bold;"&gt;slptool&lt;/span&gt; on my servers and find things like the SSH services, but my Java client just listens for 5 seconds and then gives up. If anyone has this working, I would sure appreciate a pointer or two.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11251261-112862492844266830?l=seeallhearall.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/lxpdT/~4/g4EARcDVehI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://seeallhearall.blogspot.com/feeds/112862492844266830/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=11251261&amp;postID=112862492844266830&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/11251261/posts/default/112862492844266830?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/11251261/posts/default/112862492844266830?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/lxpdT/~3/g4EARcDVehI/autodiscovery-trying-to-say-no-to.html" title="AutoDiscovery - [Trying to] Say No To Static Configuration" /><author><name>nickman</name><uri>http://www.blogger.com/profile/09238427833396441114</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://seeallhearall.blogspot.com/2005/10/autodiscovery-trying-to-say-no-to.html</feedburner:origLink></entry></feed>

