BSHDeployer

The BSH Deployer, or BeanShell Deployer allows you to deploy one-time execution scripts or even services in JBoss.

 

Scripts are plain text files with a .bsh extension and can even be hot-deployed. This gives you scripting access inside the JBoss server.

 

JBoss 3.2 and 4.0 by default ship with a service in bsh-deployer.xml, which can be referenced by the object name of jboss.deployer:service=BSHDeployer.  These scripts must end in .bsh for the BSHDeployer to pick them up and deploy them.

 

It might be helpful to refer to the BeanShell documentation on the language.  But, if you use regular Java syntax, BSH will likely understand it.

 

-


 

Your first BSH script

 

Start JBoss in the default configuration.

 

In your shell or Cygwin, execute this:

 

cat > $JBOSS_HOME/server/default/deploy/hello.bsh << EOF
System.out.println("Hello, World!");
EOF

 

Alternatively, open up a text editor and save this one line to a file to the deploy directory.

 

The JBoss log should show:

08:56:45,598 INFO  [STDOUT] ( )  Hello, World!
08:56:45,606 INFO  [BeanShellSubDeployer] ( )  javax.management.InstanceNotFoundException: 
jboss.scripts:type=BeanShell,url=file%3a/.../hello.bsh is not registered.

 

Copying to "deploy" is really all there is to deploying a script.

 

-


 

A quick service

 

You can create MBeans using a .bsh script by providing methods inside your script.  You can specify the script's ObjectName, control deployment ordering, and implement lifecycle methods.  All of these methods are optional to implement.

 

This service will appear on the JMXConsole under the example header.  There aren't (by default) many methods exposed for a service, aside from the standard service lifecycle operations, create, start, stop, destroy.

 

Here is a template script which when JBoss calls start(), will set attribute "XYZ" to 300 on "jboss:service=Server".

 

import javax.management.*;
import org.jboss.system.ServiceMBeanSupport;

ObjectName svc = new ObjectName("jboss:service=Server");
MBeanServer s;

public String objectName() {
   return "example:service=test";
}
public String[] dependsOn() {
   return new String[] { svc.toString() };
}
public void setCtx(ServiceMBeanSupport wrapper) {
   s = wrapper.getServer();
}
public void start() {
   s.setAttribute(svc, new Attribute("XYZ", 300));
}
public void stop() {
}

 

Refer to ServiceMBeanSupport for information on what this class provides.

 

-


 

Adding MBean interfaces

 

You may also expose an MBean interface (attributes and operations) by implementing the getInterfaces method:

 

import example.MyServiceMbean;
public Class[] getInterfaces() {
   return new Class[] { MyServiceMBean.class };
}

 

Your .bsh script should then implement the methods of the MyServiceMBean class.  (Note that implementing all methods is not actually required.)  This feature is fairly cumbersome, since you must provide the MBean interface in the classloader.  At some point, it may make more sense to simply write a .sar file instead.

 

It might be convenient to expose an operation, say "run", by returning Runnable.class as an interface. From this method, arbitrary Java could be invoked via the JMXConsole or Twiddle.

 

-


 

Changing an MBean Configuration Cluster-Wide

 

  1. Start two cluster instances of JBoss

  2. Create an example.bsh script (see below).

  3. Copy example.bsh into the deploy/farm directory.

  4. See it run in the console for all nodes in the cluster.

  5. Verify the MBean attribute change in all nodes using the JMXConsole.

 

Contents of example.bsh:

import javax.management.*;

MBeanServer server;

public void setCtx(ServiceMBeanSupport wrapper) {
  server = wrapper.getServer();
  print( server.getAttribute(on, "User") );
  server.setAttribute(on, new Attribute("User", "foobar") );
  print( server.getAttribute(on, "User") );
}

 

Instructions for upgrading BSH can be found here.

 

Referenced by: