XML Messaging Using JBoss
Pages: 1, 2, 3, 4
Using Quartz in JBoss
Quartz is a job scheduler. One of the provided features is an MBean, called QuartzService,
which is a standard JMX implementation in JBoss:
public class QuartzService extends ServiceMBeanSupport
implements QuartzServiceMBean {
// Constructor
// Getter/setter method ( Properties and JndiName )
// Operations
public void startService() throws Exception {
...
Scheduler scheduler = schedulerFactory.getScheduler();
scheduler.start();
...
}
public void stopService() throws Exception {
...
Scheduler scheduler = schedulerFactory.getScheduler();
scheduler.shutdown ();
...
}
}
The XML file service that you'll need for JBoss is located in this directory:
<your_install_dir>/quartz-1.4.2/src/java \
/main/org/quartz/ee/jmx/jboss/doc-files
When you deploy that XML file service, the MBean starts the scheduler based on the properties defined in quartz.properties or within the XML files service itself, and exposes the scheduler to JNDI.
Then you can get an instance of that MBean by calling a lookup() method:
InitialContext iniCtx = new InitialContext();
scheduler = (Scheduler)iniCtx.lookup("Quartz");
Once you obtain the scheduler, then you can schedule your jobs.
To schedule a job, you need to define the JobDetail and Trigger. For
JobDetail(), I use JMXInvokerJob, which is a Job implementation as a JMX MBean.
The core of the JMXInvokerJob class is:
instanceofmbeanserver.invoke ( yourObjectName,
yourMethod,
params,
signature );
This is exactly what I mention above: invoking a method within an MBean from another MBean.
So in your code, you can have something like this:
job = new JobDetail("job1", "group1", MXInvokerJob.class);
In our scenario, the following code is used:
log.info("=== DBManager.dbScheduler() for Oracle ...");
job = new JobDetail ( "OracleJob",
"OracleGroup",
JMXInvokerJob.class );
job.getJobDataMap().put ( "JMX_OBJECTNAME",
"nusa:service=DBManager" );
job.getJobDataMap().put ( "JMX_METHOD",
"processOracle" );
trigger = new CronTrigger ( "OracleTrigger",
"OracleGroup",
oracleCron );
scheduler.scheduleJob(job, trigger);
That tells the scheduler, which is an instance of QuartzService (and is an
MBean), to invoke the
processOracle() method, implemented in nusa:service=DBManager MBean,
using a cron expression.
What Quartz does in our scenario is just scheduling. The details
and nature of the job are "federated" to another MBean, called
nusa:service=DBManager.
Using Hibernate in JBoss
Hibernate is an object/relational persistence mapping, and has
more to do with the data layer. Just like Quartz, it provides an MBean
(called HibernateService). This MBean is responsible for constructing a
Hibernate SessionFactory and exposing it through JNDI.
In our scenario, the Hibernate service is defined like this in our jboss-service.xml file:
<!--
| HibernateService MBean for Oracle
-->
<mbean code="net.sf.hibernate.jmx.HibernateService"
name="jboss.jca:service=ProdOracleHibernateFactory">
<depends>jboss.jca:service=RARDeployer</depends>
<attribute name="MapResources">
mappings/Contact.hbm.xml
</attribute>
<attribute name="JndiName">
java:/OracleHibernateFactory
</attribute>
<attribute name="Datasource">
java:/OracleDS
</attribute>
<attribute name="Dialect">
net.sf.hibernate.dialect.OracleDialect
</attribute>
<attribute name="TransactionStrategy">
net.sf.hibernate.transaction.JTATransactionFactory
</attribute>
<attribute name="TransactionManagerLookupStrategy">
net.sf.hibernate.transaction.JBossTransactionManagerLookup
</attribute>
<attribute name="ShowSql">true</attribute>
<attribute name="CacheProvider">
net.sf.hibernate.cache.TreeCacheProvider
</attribute>
<attribute name="UserTransactionName">
UserTransaction
</attribute>
</mbean>
The ProdOracleHibernateFactory is the Hibernate MBean service
that deals with the Oracle database (through the JNDI namespace java:/OracleDS), using
the Contact.hbm.xml mapping file.
The next step that you have to do is to obtain an instance of
SessionFactory, as follows:
jndiName = (String)server.getAttribute(your_object_name ,"JndiName");
InitialContext ctx = new InitialContext();
sessionFactory = (SessionFactory)ctx.lookup(jndiName);
Your sessionFactory is now ready to be used. For example:
session = sessionFactory.openSession();
transaction = session.beginTransaction();
...
Although Hibernate is not a Java-XML data-binding framework--as opposed to Castor,
JAXB, XMLBeans, etc.--it provides the functionality to generate XML output.
This is handled by the Databinder.toGenericXML() or
Databinder.toXML() methods.
The structure of the XML generated is different.
Given the following mapping document:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class name="example.mapping.ICcy"
table="IProducerCcy">
<id name="ccyID" type="long"
column="ccy_id" unsaved-value="0">
<generator class="native"/>
</id>
<property name="origCcy"
column="orig_ccy"
type="string" length="3"
not-null="true"/>
<property name="settledCcy"
column="settled_ccy"
type="string" length="3"
not-null="true"/>
<property name="effectiveFrom"
column="effective_from_date"
type="date"
not-null="true"/>
<property name="ROE"
column="rate_of_exchange"
type="float"
not-null="true"/>
<property name="effectiveTo"
column="effective_to_date"
type="date"
not-null="true"/>
<property name="sendStatus"
column="send_status"
type="string" length="1"
not-null="true"/>
<property name="sendDate"
column="send_date"
type="date"
not-null="true"/>
</class>
</hibernate-mapping>
The toGenericXML() method generates the following XML structure:
<?xml version="1.0" encoding="UTF-8"?>
<hibernate-generic
datetime="04 November 2003 12:12:00">
<object class="ICcy"
package="example.mapping">
<id name="ccyID" type="long">
1</id>
<property name="origCcy" type="string">
<![CDATA[ADP]]></property>
<property name="settledCcy" type="string">
<![CDATA[GBP]]></property>
<property name="effectiveFrom" type="date">
07 October 2003</property>
<property name="roe" type="float">
211.46</property>
<property name="effectiveTo" type="date"/>
<property name="sendStatus" type="string">
<![CDATA[]]></property>
</object>
<object class="ICcy"
package="example.mapping">
<id name="ccyID" type="long">
2</id>
<property name="origCcy" type="string">
<![CDATA[AED]]></property>
<property name="settledCcy" type="string">
<![CDATA[GBP]]></property>
<property name="effectiveFrom" type="date">
07 October 2003</property>
<property name="ROE" type="float">
6.1241</property>
<property name="effectiveTo" type="date"/>
<property name="sendStatus" type="string">
<![CDATA[]]></property>
</object>
</hibernate-generic>
whereas the toXML() method generates this structure:
<?xml version="1.0" encoding="UTF-8"?>
<hibernate-custom
datetime="12 November 2003 11:47:28">
<ICcy id="N10004">
<ccyID>1</ccyID>
<origCcy>ADP</origCcy>
<settledCcy>GBP</settledCcy>
<effectiveFrom>07 October 2003
</effectiveFrom>
<ROE>211.46</ROE>
<effectiveTo>31 December 2999
</effectiveTo>
<sendStatus> </sendStatus>
<sendDate/>
</ICcy>
<ICcy id="N10026">
<ccyID>2</ccyID>
<origCcy>AED</origCcy>
<settledCcy>GBP</settledCcy>
<effectiveFrom>07 October 2003
</effectiveFrom>
<ROE>6.1241</ROE>
<effectiveTo>31 December 2999
</effectiveTo>
<sendStatus> </sendStatus>
<sendDate/>
</ICcy>
</hibernate-custom>