Creating an SMF service script for JBoss AS

This article describes how you can create a Service Manager Facility (SMF) for JBoss AS on Solaris/OpenSolaris. What is an SMF service at first ? if you are new to Solaris administration we will give here a short description about it.

SMF is a new feature of the Solaris Operating System that creates a supported, unified model for services and service management on each Solaris system. It is a core part of the Predictive Self-Healing technology available in Solaris 10.

The Service Management Facility contains several improvements compared to the standard service administration model. For example:

  • Services can be easily queried using the new svcs command and managed through the svcadm and svccfg command.
  • SMF failed services are automatically restarted in dependency order, whether they failed as the result of administrator error, software bug, or were affected by an uncorrectable hardware error.
  • If you experience problems in the boot process then you can easily debug the source of the problem because startup messages are logged and verbosity can be configured.

For a detailed list of SMF features you can visit the following link:

That being said, let’s see how this can be combined with JBoss startup/shutdown service. Historically, all releases of JBoss include a startup/shutdown script for both Windows and Unix environment (You can read more about this at this link ). However what these scripts do is controlling starting/stopping of the application server when the host is booted or shut down, or on demand.

In order to produce an SMF service for JBoss as we need two files:

  • The XML service descriptor
  • A shell script which ultimately handles starting and stopping the application server

Let’s see at first the XML descriptor, which will be named jboss.xml

<?xml version="1.0"?>
<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">

<service_bundle type='manifest' name='jboss'>

 <service name='application/jboss' type='service' version='1'>

  <!-- Wait for network interfaces to be initialized. -->
  <dependency name='network' grouping='require_all'
      restart_on='none' type='service'>
   <service_fmri value='svc:/milestone/network:default' />
  </dependency>

  <!-- Wait for all local filesystems to be mounted. -->
  <dependency name='filesystem-local' grouping='require_all'
      restart_on='none' type='service'>
   <service_fmri value='svc:/system/filesystem/local:default' />
  </dependency>

  <!-- Wait for the production database to be online
  <dependency name='database' grouping='require_all'
      restart_on='restart' type='service'>
   <service_fmri value='svc:/application/database/mysql:version_51' />
  </dependency>
  -->

  <exec_method type='method' name='start'
      exec='/lib/svc/method/jboss %m %i' timeout_seconds='60' />

  <exec_method type='method' name='stop'
      exec='/lib/svc/method/jboss %m %i' timeout_seconds='60' />

  <!-- rememer to set home dir of jboss user (usermod -d /opt/jboss5/ jboss) -->
  <property_group name="jboss" type="application">
   <propval name="home" type="astring" value="/opt/jboss5" override="true"/>
   <propval name="user" type="astring" value="jboss" override="true"/>
  </property_group>

  <!-- set this to productions values:
   # svccfg -s svc:/application/jboss:default setprop instance/host=0.0.0.0
   # svcadm refresh jboss:default
  -->
  <instance name='default' enabled='false'>
   <property_group name='instance' type='application'>
    <propval name='host' type='astring' value='127.0.0.1' />
    <propval name="partition" type="astring" value="" override="true"/>
    <propval name="udp_address" type="astring" value="" override="true"/>
    <propval name="udp_port" type="astring" value="" override="true"/>
    <propval name="properties" type="astring" value="" override="true"/>
   </property_group>
  </instance>

  <instance name='all' enabled='false'>
   <property_group name='instance' type='application'>
    <propval name='host' type='astring' value='127.0.0.1' />
    <propval name="partition" type="astring" value="" override="true"/>
    <propval name="udp_address" type="astring" value="" override="true"/>
    <propval name="udp_port" type="astring" value="" override="true"/>
    <propval name="properties" type="astring" value="" override="true"/>
   </property_group>
  </instance>

  <instance name='minimal' enabled='false'>
   <property_group name='instance' type='application'>
    <propval name='host' type='astring' value='127.0.0.1' />
    <propval name="partition" type="astring" value="" override="true"/>
    <propval name="udp_address" type="astring" value="" override="true"/>
    <propval name="udp_port" type="astring" value="" override="true"/>
    <propval name="properties" type="astring" value="" override="true"/>
   </property_group>
  </instance>

  <instance name='standard' enabled='false'>
   <property_group name='instance' type='application'>
    <propval name='host' type='astring' value='127.0.0.1' />
    <propval name="partition" type="astring" value="" override="true"/>
    <propval name="udp_address" type="astring" value="" override="true"/>
    <propval name="udp_port" type="astring" value="" override="true"/>
    <propval name="properties" type="astring" value="" override="true"/>
   </property_group>
  </instance>

  <instance name='web' enabled='false'>
   <property_group name='instance' type='application'>
    <propval name='host' type='astring' value='127.0.0.1' />
    <propval name="partition" type="astring" value="" override="true"/>
    <propval name="udp_address" type="astring" value="" override="true"/>
    <propval name="udp_port" type="astring" value="" override="true"/>
    <propval name="properties" type="astring" value="" override="true"/>
   </property_group>
  </instance>

 <stability value='Stable' />

 <template>
  <common_name>
   <loctext xml:lang='C'>JBoss AS</loctext>
  </common_name>
  <documentation>
   <doc_link name='jboss.org' uri='http://www.jboss.org/jbossas/docs.html' />
  </documentation>
 </template>

 </service>
</service_bundle>
As you can see, the XML descriptor contain in the first section two dependencies: they are related to the network interfaces and local file systems. The AS start up sequence will not begin until these two services are running.
Also (commented) you can see how you can structure a dependency with a Database (mysql) which needs to be started as well.
Then, with the <property> element we are setting some system wide property which will be used for all server configurations.
Last section, marked with <instance> contains all properties related to the single server configurations. As you can see, this script is targeted on the 5.x release of the application server. However adapting for another release is merely a matter of changing the <instance> property so that it matches the available server configurations.
If you want to change some properties without touching the XML descriptor, then you can simply use the svccfg command as in this example:
# svccfg -s svc:/application/jboss:default setprop instance/host=0.0.0.0
# svcadm refresh jboss:default
Here we are setting the instance property “host” to 0.0.0.0 for the configuration default. Next comand (refresh) takes care to refresh the SMF configuration.
If the application server was up and running you need, additionally to restart it with the svcadm shell command.
# svcadm restart jboss:default
Installing the SMF script
A tar.gz archive for this script can be downloaded here.
Installing is just a matter of unpacking the archive:
# gzcat jboss-smf.tar.gz | tar xf –
then we need to copy the script in the library folder and add the execution permission to it:
# cp jboss /lib/svc/method/
# chmod +x /lib/svc/method/jboss
Good. Now just import the XML descriptor in our database of services, by using the svccfg command :
# svccfg import jboss.xml
Now the configuration is completed. You can verify that all server instances are availabe by querying the service db with the svcs command:
# svcs -a|grep jboss
disabled 9:46:57 svc:/application/jboss:all
disabled 9:46:57 svc:/application/jboss:default
disabled 9:46:57 svc:/application/jboss:web
disabled 9:46:57 svc:/application/jboss:minimal
disabled 14:16:17 svc:/application/jboss:standard
In order to start one of these instances, just issue
# svcadm enable jboss:default
This will start the default server configuration for the configured host.
The original article (for italian readers) can be read from Luca’s Blog here. There you can find plenty of other useful articles concerning Solaris and Unix systems.