Hi,
NOTE: this article is focused on JBoss AS6 and earlier versions. For JBoss AS7 service archives please refer to: http://middlewaremagic.com/jboss/?p=366

SAR files are called as Service Archives. The extension of SAR files are *.sar which contains a “META-INF/jboss-service.xml” file, this file describes the custom MBeans which has to be exposed at the time of deployment or JBoss Startup. JBoss’s service archive architecture is based on the JMX and the SAR files which are basically JBoss specific can be deployed in the jboss inorder to publish your MBean based services. At the time of JBoss startup these service archive deployer (SARDeployer) instantiates the JBoss service classes and exposes them as manageable beans through JMX. These beans can be viewed and edited from the jmx-console as well.

One of the best usage of the service archieve is to monitor the servers activities. In this simple example we will try to get JBoss Server’s basic informations using the JBoss MBean “jboss.system:type=Server” using our SAR file.

Step1). Create a directory somewhere in your file system like “/home/userone/ServerMonitorService.sar”.

Step2). Create an MBean interface by extending the interface “org.jboss.system.ServiceMBean” as following. “MyServerMonitorMBean.java” inside the “/home/userone/ServerMonitorService.sar” directory.

package custom.mbean;
import org.jboss.system.ServiceMBean;
public interface MyServerMonitorMBean extends org.jboss.system.ServiceMBean
  {
      public void setFrequency(String frequency);
      public String getFrequency();
  }

Step3). Now provide an implementation class of the above MBean interface as “MyServerMonitor.java” inside the directory “/home/userone/ServerMonitorService.sar”. Make sure that this class extends the “org.jboss.system.ServiceMBeanSupport” class because this class provides some useful methods like “startService()” and “stopService()” which are the life cycle methids of our beans.

package custom.mbean;
import javax.management.*;
import java.io.*;
import java.util.*;
import java.rmi.*;
import javax.naming.*;
public class MyServerMonitor extends org.jboss.system.ServiceMBeanSupport implements MyServerMonitorMBean
  {
      boolean flag=true;
      public String Frequency;
      private MBeanServerConnection server=null;
      public void setFrequency(String Frequency)
      {
          System.out.println("nt Server Watch Frequency is set to : "+Frequency+"-Milliseconds");
          this.Frequency=Frequency;
      }
      public String getFrequency()
      {
          System.out.println("nt Server Watch Frequency is set to : "+Frequency+"-Milliseconds");
          return this.Frequency;
      }
      public MyServerMonitor()
      {
         System.out.println("nnt ServiceMonitorMBean is activated...inside ServiceMonitor() constructor--setting default Frequency=10000 Miliseconds");;
      }

     public void startService() throws Exception
      {
         log.info("nntStarting MyServerMonitor");
            try{
            Hashtable ht=new Hashtable();
            ht.put(Context.INITIAL_CONTEXT_FACTORY,"org.jboss.security.jndi.JndiLoginInitialContextFactory");
            ht.put(Context.PROVIDER_URL,"localhost:1099");
            ht.put(Context.SECURITY_PRINCIPAL,"admin");
            ht.put(Context.SECURITY_CREDENTIALS,"admin");
            System.out.println("nt 1- Gotting InitialContext...... ");
            Context ctx = new InitialContext(ht);
            System.out.println("nt 2- Got InitialContext: "+ctx);
            server = (MBeanServerConnection) ctx.lookup("jmx/invoker/RMIAdaptor");
            }
            catch(Exception e)
            {
                System.out.println("nnt Exception inside MyServerMonitor..."+e);
            }
            Frequency="5000";
            ServerMonitorRunner runner=new ServerMonitorRunner();
      }

      public void monitor() throws Exception
      {
            String data="";
            data=data+"nnt===================MyServerMonitor.monitor()===================";
            data=data+"nBuildOS = "+ (String)server.getAttribute(new ObjectName("jboss.system:type=Server"), new String("BuildOS"));
            data=data+"nVersionName = "+ (String)server.getAttribute(new ObjectName("jboss.system:type=Server"), new String("VersionName"));
            data=data+"nBuildDate = "+ (String)server.getAttribute(new ObjectName("jboss.system:type=Server"), new String("BuildDate"));
            data=data+"nInShutdown = "+ (Boolean)server.getAttribute(new ObjectName("jboss.system:type=Server"), new String("InShutdown"));
            data=data+"nStartDate = "+ (java.util.Date)server.getAttribute(new ObjectName("jboss.system:type=Server"), new String("StartDate"));
            data=data+"nStarted = "+ (Boolean)server.getAttribute(new ObjectName("jboss.system:type=Server"), new String("Started"));
            data=data+"nBuildNumber = "+ (String)server.getAttribute(new ObjectName("jboss.system:type=Server"), new String("BuildNumber"));
            data=data+"nBuildJVM = "+ (String)server.getAttribute(new ObjectName("jboss.system:type=Server"), new String("BuildJVM"));
            data=data+"nVersionNumber = "+ (String)server.getAttribute(new ObjectName("jboss.system:type=Server"), new String("VersionNumber"));
            data=data+"nt===============================================================";
            System.out.println(data);
      }

     public void stopService() throws Exception
      {
         log.info("nntStopping MyServerMonitor");
      }
     class ServerMonitorRunner extends Thread
       {
           ServerMonitorRunner()
            {
                this.start();
            }
           public void run()
             {
                for(; 😉
                  {
                    try{
                          Thread.sleep(Integer.parseInt(Frequency));
                          monitor();
                       }
                    catch(InterruptedException ie){ ie.printStackTrace();}
                    catch(Exception e){ e.printStackTrace();}

                  }
             }
       }
  }

Step4). Now the most important part, here we need to declare the MBean inside the “/home/userone/ServerMonitorService.sar/META-INF/jboss-service.xml” file as following:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE server>
<server>
    <mbean code="custom.mbean.MyServerMonitor" name="service.server.monitor:service=MyMonitor">
         <attribute name="Frequency">5000</attribute>
         <depends>jboss.jmx:type=adaptor,name=Invoker,protocol=jrmp,service=proxyFactory</depends>
    </mbean>
</server>

NOTE: here inside the tag we have used the tag because our MBean is dependent on another MBean “jboss.jmx:type=adaptor,name=Invoker,protocol=jrmp,service=proxyFactory”…this is why because our MBean code is performing ic.lookup() using the “jmx/invoker/RMIAdaptor” so we need to make sure that the “jboss.jmx:type=adaptor,name=Invoker,protocol=jrmp,service=proxyFactory” service gets activated before our MBean. otherwise we will see NullPointerException while performing lookup inside our bean.

Step5). Deploy the “ServerMonitorService.sar” inside the “${PROFILE}/deploy” directory of your JBoss. And then you will start seeing the following kind of messages in the server Console :

12:55:53,949 INFO  [STDOUT]
	 ServiceMonitorMBean is activated...inside ServiceMonitor() constructor--setting default Frequency=10000 Miliseconds
12:55:53,952 INFO  [STDOUT]
	 Server Watch Frequency is set to : 5000-Milliseconds
12:55:53,952 INFO  [MyServerMonitor]

	Starting MyServerMonitor
12:55:53,952 INFO  [STDOUT]
	 1- Gotting InitialContext......
12:55:53,964 INFO  [STDOUT]
	 2- Got InitialContext: javax.naming.InitialContext@588a4b96
12:55:59,167 INFO  [STDOUT]

	===================MyServerMonitor.monitor()===================
BuildOS = Linux(i386,2.6.18-194.8.1.el5)
VersionName = JBoss AS
InShutdown = false
StartDate = Sun Oct 16 12:19:59 IST 2011
Started = true
BuildJVM = 17.0-b16(Sun Microsystems Inc.)
VersionNumber = 6.0.
	===============================================================

The MyServerMonitor.monitor() will be executed after every 5 Seconds as we have set this frequency as 5 seconds inside the jboss-service.xml file.

Step6). If you want to change this frequency to something else then you can login to jmx-console and then search for “service.server.monitor” in the left Panel then by clicking on it you will be able to see the frequency which you can change.

.
.
Thanks
Middleware Magic Team

If you enjoyed this post, please consider leaving a comment or subscribing to the RSS feed to have future articles delivered to your feed reader.