« July 2006 »
SunMonTueWedThuFriSat
  
1
3
4
5
6
9
11
12
13
16
17
19
20
23
24
26
27
28
31
  
       
Today
XML

Blog::Navigation

GetJava Download Button
Get the Source
Personal Blog

Blog::Referers

Today's Page Hits: 970

Powered by Roller Weblogger.
« Previous month (Jun 2006) | Main | Next month (Aug 2006) »
20060830 Wednesday August 30, 2006

Scriptlets

Just added scriptlet application to http://scripting.dev.java.net

A Scriptlet is a Java applet written in JavaScript. With scriptlets, developers use a predefined applet class (called com.sun.scriptlet.Scriptlet) and define an applet param which identifies a JavaScript. The JavaScript code can define one or more script functions to "override" applet's methods such as start, stop, init, destroy or paint.

By just defining paint function, scriptlet becomes equivalent to the new canvas tag. But unlike canvas tag, scriptlet functions can access the entire JDK API. The current applet object is exposed as first argument to scriptlet's functions. For example, using this applet argument, scriptlets can play audio (by calling play method). With just the knowledge of JavaScript and Java API, very nice applets can be written.

Using Java-to-Javascript Communication between Java to browser's built-in JavaScript engine, a global variable named window is defined. This window variable can be used by scriptlet scripts to access browser's script objects. For example, window.location.href returns the URL of the currently visited web page. Similarly window.document can be used to get the DOM document object of the current HTML page. Few simple scriptlets are in the applications/scriptlet/src/scriptlets directory of the scripting project.



( Aug 30 2006, 09:07:34 PM IST ) Permalink Comments [1] del.icio.us | furl | simpy | slashdot | technorati | digg

20060829 Tuesday August 29, 2006

Multiple language programming in JDK

Phobos is a lightweight, scripting-friendly, web application environment running on the Java platform. Primary language used in Phobos project is JavaScript - but it is possible to use any JSR-223 compliant language.

Sometimes you may even want to use more than one language in the same application. For example, there is a calculator sample application in Phobos. This application has a simple HTML GUI for a four-function calculator. The add, subtract, multiply and divide operations of this application are implemented as JavaScript number arithmetic - which is same as Java's double precision arithmetic. For example, Let us assume that you want to extend this application to do Java BigDecimal arithmetic instead of double arithmetic. Ofcourse, you can call Java API for BigDecimal arithmetic from JavaScript. But, you can implement this feature very easily using the JEP script engine!

I did the following experiment after expanding and installing the Phobos sample calculator.war under Apache Tomcat [I used Tomcat 5.5].

I copied the following jar files to webapp's lib directory WEB-INF/lib:

  1. jep-engine.jar [available from http://scripting.dev.java.net project] This is the JSR-223 script engine for JEP.
  2. jep-2.4.0.jar
  3. ext-1.1.0.jar
  4. Jama-1.0.2.jar

The last three jar files can be downloaded from http://www.singularsys.com/jep/. If CVS checked out complete sources from scripting.dev.java.net, these jar files are under scripting/engines/jep/lib directory.

Then, I made the following changes to WEB-INF/application/startup.js. Note that this script executes when the calculator application is started for the first time. In this script, I've created a script engine for JEP and stored it in application object.

// application startup script



// creata a script engine manager
application.smanager = new Packages.javax.script.ScriptEngineManager();

// create a Java Math Expression Parser (JEP) script engine
application.jepEngine = application.smanager.getEngineByName("jep");

/* Set the JEP mode to be "bigreal" - with this mode JEP engine
 * arithmetic is done using java.math.BigDecimal objects
 * rather than double values.
 */
application.jepEngine.eval("mode(\"bigreal\")");


After that, I made the following changes to WEB-INF/application/controller/calculator.js: Mainly, the calculator's compute function is modified as follows:

    POST: function() {
        var value = request.getParameter("value");
        var operand = request.getParameter("operand");
        var operator = request.getParameter("operator")

       /*
        * Who needs the switch statement?  :-)
        */
        value = ({ add: function(x,y) { return application.jepEngine.eval(x + "+" +y); },
                   subtract: function(x,y) { return application.jepEngine.eval(x + "-" + y); },
                   multiply: function(x,y) { return application.jepEngine.eval(x + "*" + y); },
                   divide: function(x,y) { return y == 0 ? 0 : application.jepEngine.eval(x + "/" + y); },
                 }[operator])(value, operand);
                    
    [... more code deleted for brevity ...]


Instead of converting the request parameters as JavaScript numbers (like the original sample did), I create and evaluate JEP expressions in add, subtract, multiply and divide methods. After making the above changes, I started Tomcat and visited http://localhost:8080/calculator. Now, with the same calculator interface, the user can do BigDecimal arithmetic! What's more - we can easily change JEP "mode" to - say vector arithmetic.

If we make the following change to startup.js,


application.jepEngine.eval("mode(\"vector\")");

then the calculator supports vector/matrix/tensor arithmetic! For example, we can enter [3232.343243, 4324] and [3432, 3434.353454] as input values and choose "add" option to do vector addition.

Another example of mixing languages: you may use JavaScript Templates script engine to generate dynamic HTML content using TrimPath JavaScript Templates

With JSR-223 API, it is eary to call between scripts written in different scripting languages - provided there are JSR-223 script engines for the languages involved. It is very easy call eval. If you want more closer co-operation between scripts - like calling a function implemented in another scripting language or implementing a Java interface in script (which could be called from other scripting language or from Java), then there is Invocable interface.



( Aug 29 2006, 04:13:30 PM IST ) Permalink del.icio.us | furl | simpy | slashdot | technorati | digg

20060825 Friday August 25, 2006

JSR-223 engine for Java Math Expressions Parser

Java Math Expressions Parser supports BigInteger, BigDecimal, rational, complex, vector/matrix/tensor expressions. Just added JSR-223 script engine for that. As usual, the sources are available at http://scripting.dev.java.net.

I'd like to add a script engine (or extend one of the existing engines like JEP engine) to support interval arithmetic. I came across Frink - but it is not open source (nor the interfaces seem available). Other library that I came across is this: http://interval.sourceforge.net.



( Aug 25 2006, 06:48:31 PM IST ) Permalink del.icio.us | furl | simpy | slashdot | technorati | digg

20060822 Tuesday August 22, 2006

Script engines written in JavaScript

JDK 6 contains javax.script (JSR-223) API and a Rhino based sample JavaScript engine. http://scripting.dev.java.net project has been created to develop JSR-223 engines for other languages and useful, demo applications that use scripting.

Just added two more script engines to http://scripting.dev.java.net. Unlike other script engines, this script engine is implemented in JavaScript. These engines implement JSP/ASP/PHP-like templating for JavaScript.

  1. ejs - embedded JavaScript - implements <%= expr %>, <% code %>
  2. jst - JavaScript Templates - this is based on TrimPath's JavaScript Templates.

It should be possible to use these script engines in Java code as well - because these implement javax.script API as required. But, you have to create a JavaScript engine and eval the corresponding scripts. And then call ejsScriptEngineFactory or jstScriptEngineFactory function to create javax.script.ScriptEngineFactory for these engines.

It should be possible to use the jst and ejs engines with Phobos web application framework. [though I am yet to test that part!]

I came across these other language implementations on JavaScript:

  1. Oberon Script. A lightweight Compiler and Runtime System for the Web
  2. Scheme Implementation in JavaScript

Also, it seems that JavaScript 2 would be implemented as a translater that translates js2 to js1 (atleast to startwith).



( Aug 22 2006, 12:19:49 PM IST ) Permalink del.icio.us | furl | simpy | slashdot | technorati | digg

20060821 Monday August 21, 2006

Scriptpad sample in build 96

JDK 6 build 96 contains a new sample application called "scriptpad". Scriptpad is a simple notepad-like editor written more or less completely in JavaScript. There is a simple driver code in Java - which uses javax.script API. This sample demonstrates Java-to-JavaScript communication as well.



( Aug 21 2006, 08:38:22 PM IST ) Permalink del.icio.us | furl | simpy | slashdot | technorati | digg

20060818 Friday August 18, 2006

JSR-223 engine for Jaskell

Just added JSR-223 script engine for Jaskell (http://jaskell.codehaus.org/). Jaskell in author's words:

Jaskell is a functional scripting programming language that runs in JVM. The name "Jaskell" stands for Java-Haskell, Haskell being the famous pure functional programming language.

Jaskell is a lazy functional scripting language for Java. It features higher-order function, function currying, string interpolation, lazy evaluation, monad, dynamic typing, simple syntax and semantics etc.

As usual, engine source and binary are available at https://scripting.dev.java.net/



( Aug 18 2006, 11:35:44 AM IST ) Permalink del.icio.us | furl | simpy | slashdot | technorati | digg

20060815 Tuesday August 15, 2006

JSR-223 script engine for browser's JS interpreter?

You may have used Java-to-JavaScript communication in the context of the Java plugin. This API allows a Java applet to call/use JavaScript interpreter of the web browser.

When you hammer, everything looks like a nail :-) I've implemented JSR-223 script engine by wrapping netscape.javascript API. As usual, it is available at https://scripting.dev.java.net

This script engine uses the JavaScript interpreter embedded in web browsers. Unlike the other script engines, this script engine is not expected to work on all settings. This engine works only inside the browsers - which effectively means only Java applets can make use of this script engine. I call this script engine as "browserjs" engine.

Because this script engine uses LiveConnect, the applet's APPLET tag has to include mayscript="true" attribute so that browser's window object can be obtained. Also, user has to set Applet object as a variable named "applet" in the current ScriptContext.

Following is a simple Applet that uses browser's JS interpreter through javax.script API.

import java.applet.*;
import javax.script.*;

public class ScriptClient extends Applet {
    private ScriptEngine engine;

    public void init() {
        ClassLoader myloader = getClass().getClassLoader();
        ScriptEngineManager manager = new ScriptEngineManager(myloader);
        engine = manager.getEngineByName("BrowserJS");
        try {
            engine.put("applet", this);
            // eval alert..
            engine.eval("alert('hello world');");
            // call alert...
            ((Invocable)engine).invokeFunction("alert", "hello, world!");
        } catch (ScriptException exp) {
            throw new RuntimeException(exp);
        } catch (NoSuchMethodException nsme) {
            throw new RuntimeException(nsme);
        }
    }  
}

How does this "browserjs" JavaScript script engine compares to the bundled Rhino-based JavaScript engine in JDK 6?

In addition to adding this "new" script engine, I've updated scripting.dev.java.net for the following:



( Aug 15 2006, 12:49:51 PM IST ) Permalink del.icio.us | furl | simpy | slashdot | technorati | digg

20060814 Monday August 14, 2006

Using DTrace Java API

As I wrote in my earlier post, I am running OpenSolaris - Nevada build 38 on my laptop [And Venky promptly pasted "I boot OpenSolaris" sticker on it :-) ]. With Nevada, there is a Java API for DTrace.

I thought of playing with this API (/usr/share/lib/java/javadoc/dtrace/html/fast.html) There are simple Java examples under /usr/share/lib/java/javadoc/dtrace/examples. But, these days I prefer to do exploratory programming with JavaScript that is bundled in Java SE 6 - particularly if I'm going to write a simple class with just the main method!.

The DTrace Java API has the notion of "consumers" - think of consumer as a particular DTrace session. With a consumer, you register one or more "listeners" and then compile one or more D-scripts. Wait for events in your listener after calling "go" on the consumer...

File: test.js

// import package org.opensolaris.os.dtrace
importPackage(org.opensolaris.os.dtrace);

// create a LocalConsumer
var consumer = new LocalConsumer();

/*
 * Register a callback listener. The listener is of the interface
 * type org.opensolaris.os.dtrace.ConsumerListener. But, in JavaScript
 * we can pass a function and that will be wrapped as interface!
 */

consumer.addConsumerListener(function (evt) {
        // if we get probe data, then print it
        if (evt instanceof DataEvent) {
            println(evt.probeData);
        }
});

// open consumer, no special options passed
consumer.open([]);

/* 
 * Note that jrunscript passed "arguments" array that has command
 * line arguments to the current JavaScript.
 *
 * We take the first command line argument as D-script file to use
 * and pass the remaining arguments are passed as macro arguments
 * (which can be accessed as $1, $2... in the D-script)
 */

// Compile the D-script file
consumer.compile(new java.io.File(arguments(0), arguments.slice(1));

// enable the consumer
consumer.enable();

// "start" the consumer so that we get notifications in the
// callback registered above
consumer.go();

To run the above script, I used the following command line:

jrunscript -cp /usr/share/lib/java/dtrace.jar -f test.js hello.d

Note that I've put dtrace.jar in the classpath. "hello.d" is the D-script passed as first argument.

File: hello.d:

:::BEGIN {
    trace("hello, world");
    exit(0);
}

When we run the above script, "hello, world" is printed as expected. How about accessing DTrace aggregates? Consider the following simple D-script that populates an aggregate.

File: histo.d

// object-alloc probe is fired whenever a Java object is allocated

hotspot$1:::object-alloc {
    // arg1 for this probe is name of the Java class
    // whose object is being allocated

    // arg2 is length of the class name string
    self->str = (string) copyin(arg1, arg2);
    self->str[arg2] = '\0';

    // arg3 is size of the object being allocated

    // We update an aggregate whose key is the class name 
    // and the value is total size of objects allocated so far.
    @histo[(string) self->str] = sum(arg3);
}

How about a script that prints the above histogram once every second? I copied "test.js" to "histo.js" and added the following lines:

File: histo.js

// same code as in "test.js" followed by these lines..
var a;
do {
    java.lang.Thread.sleep(1000);
    // get all aggregations from consumer
    a = consumer.aggregate;
    if (! a.asMap().empty()) {
        // get "histo" aggregation
        var histo = a.getAggregation("histo");

        // get iterator of AggregationRecords
        var itr = histo.records.iterator();

        while (itr.hasNext()) {
            var rec = itr.next();
            // in our aggreation, the key tuple has only one component
            // - the class name. 
            println(rec.tuple.get(0) + '\t' + rec.value);
        }
    }
    println("===========================================");
} while (consumer.isRunning());


To enable object-alloc probe, we have to start your Java application with -XX:+ExtendedDTraceProbes flag. I started the Java2D demo application (bundled with JDK) with the following command line:


java -XX:+ExtendedDTraceProbes $JDK_HOME/demo/jfc/Java2D/Java2Demo.jar

Then, I ran the above "histo.js" script with the following command line:

jrunscript -cp /usr/share/lib/java/dtrace.jar -f histo.js histo.d 790

where 790 is the process id above mentioned Java2D demo app. (Note: you can find process ids of all your Java apps using jps).

Of course, it is not much fun in just printing the histogram by JavaScript - you may as well do the same with D-script itself. But, you may want to show histogram in a fancy GUI or do some "client side" post-processing of trace data and so on. You can write such programs using DTrace Java API in Java or any of the scripting languages for the Java Platform. With languages that support UNIX shell style heredocs (for example, Groovy, Jython) it is easier to embed D-script as a string and use Consumer.compile(String program, String... args) that accepts D-script as a String rather than file. But, what if you don't want to code but visualize using DTrace? You may want to check out Chime!

References



( Aug 14 2006, 01:44:09 PM IST ) Permalink del.icio.us | furl | simpy | slashdot | technorati | digg

20060810 Thursday August 10, 2006

doesNotUnderstand in Groovy

What is doesNotUnderstand method? From Reflective Facilities in Smalltalk-80 by Brian Foote and Ralph E. Johnson:

When a message is sent to a Smalltalk-80 object, the method dictionaries associated with that object's class and its superclasses are searched at runtime. If none of these classes implement a method for a given message, the Smalltalk virtual machine sends the object the message doesNotUnderstand:. The original message selector and message arguments are bundled together in a Message object and passed as the argument to doesNotUnderstand:. The default method for this message is stored in class Object. This method invokes the Smalltalk debugger, since sending an object a message it does not implement is usually a sign of programmer error. However, objects that override doesNotUnderstand: can intercept unimplemented message at runtime, and process them as they see fit.

Java being a statically typed language, javac will not compile if a method can not be found at compile time. Time to look at some code...



class Main {
   public static void main(String[] args) {
       // see Person class below..
       Person p = new Person();
       System.out.println("Starting...");

       // call methods that are defined in Person class
       p.work();
       p.greet();

       // call methods that are not defined in Person 
       // or it's superclass       
       p.surfTheNet();
       p.writeBlog();
   }
}

class Person {

   public void work() { 
       System.out.println("Okay, I'll work tomorrow!");
   }

   public void greet() { 
       System.out.println("Hello, World!");
   }
  
   public Object invokeMethod(String name, Object args) {
       System.out.println("Why are you calling " + name + "?");
   }
}


If you attempted javac against above program, you will get
Main.java:15: cannot find symbol
symbol  : method surfTheNet()
location: class Person
       p.surfTheNet();
        ^
Main.java:16: cannot find symbol
symbol  : method writeBlog()
location: class Person
       p.writeBlog();
        ^
2 errors

You may have heard and/or used dynamic proxies with Java. With dynamic proxies, you implement all methods of one or more interfaces by a single invoke of an InvocationHandler.

Imagine if you could do something similar for classes as well (not just for interfaces). i.e., all method calls on objects of your class will end-up calling a single (special) "invokeMethod" method. Or think of something slightly restricted. If a method of matching name (and signature) is found in your class (or any of the superclasses) then that method will be called - if no such method is found, then a special method called "invokeMethod" will be called Groovy supports both the options.

Output with above program from Groovy is as follows:
Starting...
Okay, I'll work tomorrow!
Hello, World!
Why are you calling surfTheNet?
Why are you calling writeBlog?

i.e., For the methods not found in Person class, Groovy calls invokeMethod method. Now, what if you want to "trap" all method calls, regardless of whether the method is defined in your class or not. It turns out that you can that in Groovy. We make the following change to Person class:



class Person implements GroovyInterceptable {
   public void work() { 
       System.out.println("Okay, I'll work tomorrow!");
   }

   public void greet() { 
       System.out.println("Hello, World!");
   }

   public Object invokeMethod(String name, Object args) {
       System.out.println("Why are you calling " + name + "?");
   }
}


Output from Groovy after the above change is as follows:
Starting...
Why are you calling work?
Why are you calling greet?
Why are you calling surfTheNet?
Why are you calling writeBlog?

When you implement groovy.lang.GroovyInterceptable interface, you are essentially saying that for any method call on the objects of this class, call invokeMethod method.

What about properties? You can implement special methods getProperty(String) and putProperty(String, Object) methods for properties. These are used in the implementation of groovy.util.GroovyMBean - which I mentioned in my blog entry titled Groovier jconsole.

Actually, Groovy's Meta Object Protocol is slightly more complex than what I described. But then that is a topic for another blog entry .... :-)



( Aug 10 2006, 11:24:34 AM IST ) Permalink del.icio.us | furl | simpy | slashdot | technorati | digg

20060808 Tuesday August 08, 2006

Multimethods in Groovy

Let us look at a simple class called "Person".



class Person {
    private String name;
    public Person(String name) {
        this.name = name;
    }
    public Person() {
        this.name = "";
    }
    
    public boolean equals(Object o) {
        System.out.println("Huh! not comparable!");
        return false;
    }

    // This does not override java.lang.Object.equals(Object) method
    // See also: Java(TM) Puzzlers: Traps, Pitfalls, and Corner Cases 
    // Puzzle 58 (It is easy to overload when you intend to override!)
    public boolean equals(Person emp) {        
        return name.equals(emp.name);
    }

    public static void main(String[] args) {
        Object e1 = new Person("Sundar");
        Object e2 = new Person("Rajan");
        System.out.println(e1.equals(e2));
        System.out.println(e1.equals(e1));
        System.out.println(e1.equals("Sundar"));   
    }
}

Output of the above program is as below:
Huh! not comparable!
false
Huh! not comparable!
false
Huh! not comparable!
false
This is because equals(Object) is selected for all equals calls in the main method. If we change the main as

    public static void main(String[] args) {
        Person e1 = new Person("Sundar");
        Person e2 = new Person("Rajan");
        System.out.println(e1.equals(e2));
        System.out.println(e1.equals(e1));
        System.out.println(e1.equals("Sundar"));   
    }

We get this output:
false
true
Huh! not comparable!
false

This is because javac's overload resolution mechanism has selected the "right" method (at the compile time) for us!

Let us check the output of the unmodified (i.e., main not changed as above) with Groovy. I'll use

Groovy output:

jrunscript -cp ../build/groovy-engine.jar;../lib/groovy-all-1.0-JSR-06.jar  -l groovy Person.java

false
true
Huh! not comparable!
false

Groovy invokes the "correct" method in all cases. This is because Groovy supports multimethods. The method actully invoked depends not only on the "receiver" - but, also on the dynamic type of the arguments. For each equals call, the correct equals method is chosen (regardless of compiled time type declared in the program).

There are two different variants of multimethods:

If you want to know more about "binary methods" (single argument methods where argument type is same as that of the "receiver" - like the equals method), then you may want to refer to On Binary Methods



( Aug 08 2006, 06:48:01 PM IST ) Permalink Comments [4] del.icio.us | furl | simpy | slashdot | technorati | digg

20060807 Monday August 07, 2006

Using Apache DB Derby from JavaScript

Apache DB Derby is co-bundled with Mustang (Java SE 6). And Mozilla Rhino based JSR-223 script engine for JavaScript is also bundled with Mustang. How about accessing Derby database from JavaScript? I tried the following script...



// constructor to create DB object. Accepts user, password and DB name
function DB(user, password, db) {
    var driver = new org.apache.derby.jdbc.EmbeddedDriver();
    var props = new java.util.Properties();
    props.put("user", user);
    props.put("password", password);
    this.conn = java.sql.DriverManager.getConnection("jdbc:derby:" +
                db + ";create=true", props);
}

// wraps the ResultSet as an Iterator
DB.prototype.query = function (str) {
    var stat = this.conn.createStatement();
    var rs = stat.executeQuery(str);

    return new java.util.Iterator() {
            hasNext: function() { 
                return rs.next();
            },
            next: function() {
                return new JSAdapter() {
                    __has__: function (name) {
                       try {
                           rs.findColumn(name);
                           return true;
                       } catch (e) {
                           println(e);
                           return false;
                       }
                    },
                    __get__: function (name) {
                        return rs.getObject(name);
                    }
                };
            },
            remove: function() {
                rs.deleteRow();
            }
        };
}

// execute query and update
DB.prototype.execute = function (str) {
    var stat = this.conn.createStatement();
    return stat.execute(str);
}

DB.prototype.update = function (str) {
    var stat = this.conn.createStatement();
    return this.conn.executeUpdate(str);
}

// dispose the connection
DB.prototype.dispose = function() {
    this.conn.close();
}

// simple "main" function that uses the above db "API"!

function main() {
    var db = new DB("user1", "user1", "derbyDB");
    db.execute("create table derbyDB(num int, addr varchar(40))");  
    db.execute("insert into derbyDB values (1956,'Webster St.')");
    db.execute("insert into derbyDB values (1910,'Union St.')");
    db.execute(
          "update derbyDB set num=180, addr='Grand Ave.' where num=1956");

    var res = db.query(
                    "SELECT num, addr FROM derbyDB ORDER BY num");

    // because of JSAdapter, we can access
    // columns as "fields" of the "row object".
    while (res.hasNext()) {
        var row = res.next();
        println(row.num + "\t" + row.addr);
    }
    db.dispose();
}

main();


With the above code, I got the following output:

jrunscript -cp D:\jdk1.6.0\db\lib\derby.jar -f db.js
180     Grand Ave.
1910    Union St.

Note that I've put derby.jar in the classpath so that Derby classes can be accessed from the scripts.



( Aug 07 2006, 07:58:08 PM IST ) Permalink del.icio.us | furl | simpy | slashdot | technorati | digg

20060802 Wednesday August 02, 2006

Groovier jconsole!

I blogged about script shell plugin for jconsole. With script shell plugin, you can use JavaScript to view/analyze JMX MBeans. This is particularly useful if you are going to debug your own MBeans -- although jconsole is a generic JMX client, you can use scripting to debug your MBeans. But, what if your scripting language of choice is not JavaScript? How about Groovy? It turns out that it is possible to use any language for which you have JSR-223 script engine.

Using Groovy with jconsole

Steps to use Groovy with jconsole script shell/console plugin:
  1. download https://mustang.dev.java.net :-)
  2. download Groovy - available from http://dist.codehaus.org/groovy/distributions/ (groovy-all-1.0-JSR-06.jar)
  3. download JSR-223 script engine for Groovy - available from https://scripting.dev.java.net (groovy-engine.jar)
  4. Drop both groovy-all-1.0-JSR-06.jar and groovy-engine.jar in $JDK_HOME/jre/lib/ext - note that in general it is not advisable to drop arbitrary jar files under JRE's ext directory -- there are security implications. But, this is just for experiment!
  5. Now, use the following command to start jconsole:
    
        jconsole -J-Dcom.sun.demo.jconsole.console.language=groovy -pluginpath $JDK_HOME/demo/scripting/jconsole-plugin/jconsole-plugin.jar
    
    

With -J-Dcom.sun.demo.jconsole.console.language=groovy option, you are specifying to use Groovy as the language for script shell plugin. You will see something like this:


There is MBean support in Groovy -- you may want to refer to the class groovy.util.GroovyMBean. Here is the Groovy "session" with jconsole:(Note: plugin is a pre-defined variable of type JConsolePlugin)


groovy>plugin.context
pid: 1876 java2demo.jar
groovy>conn = plugin.context.getMBeanServerConnection()
javax.management.remote.rmi.RMIConnector$RemoteMBeanServerConnection@16c1bce
groovy>def objectName(str) { return new javax.management.ObjectName(str); }
groovy>def mbean(str) { return new groovy.util.GroovyMBean(conn, objectName(str)); }
groovy>classLoading = mbean("java.lang:type=ClassLoading")
MBean Name:
  java.lang:type=ClassLoading
  
Attributes:
  (r) int LoadedClassCount
  (r) long TotalLoadedClassCount
  (r) long UnloadedClassCount
  (rw) boolean Verbose
groovy>classLoading.LoadedClassCount
2571
groovy>classLoading.UnloadedClassCount
105
groovy>memoryMBean = mbean("java.lang:type=Memory")
MBean Name:
  java.lang:type=Memory
  
Attributes:
  (r) javax.management.openmbean.CompositeData HeapMemoryUsage
  (r) javax.management.openmbean.CompositeData NonHeapMemoryUsage
  (r) int ObjectPendingFinalizationCount
  (rw) boolean Verbose
Operations:
  void gc()
groovy>

You can customize further by defining a file named jconsole.groovy under your home directory. This will be loaded by script shell plugin just after initialization. You can define classes, functions in jconsole.groovy that could be called interactively in groovy script shell prompt.



( Aug 02 2006, 08:34:06 PM IST ) Permalink Comments [1] del.icio.us | furl | simpy | slashdot | technorati | digg

Copyright (C) 2005, A. Sundararajan's Weblog