!!! This page is OUT OF DATE - scoping is no longer necessary with JBM
Deploying a scoped MDB container
An MDB container that connects to a JBoss Messaging instance requires access to the client-side Messaging libraries and their dependencies (AOP, Remoting, etc.). If the JBoss Messaging server is co-located (same VM), deploying the container is as simple as dropping the EJB jar in the server's deployment directory. Some simple precautions need to be taken, and the procedure is described in detail in the first part of this document ("Co-located JBoss Messaging instance").
However, if the JBoss Messaging server is remote, the MDB container deployment must include the client-side Messaging dependencies, or the MDB container must be given access to the client-side Messaging dependencies by being deployed in a class loading domain that contains those. The procedure is described in detail in the second part of the document ("Remote JBoss Messaging instance" and "Remoting JBoss Messaging instance (Alternate method)").
The procedures described in this document have been tested with JBoss 4.0.4.GA and JBoss 4.0.3SP1.
1. Co-located JBoss Messaging instance
1.1 Make sure JNDI call by reference sematics is enabled
Modify the Naming (JNDI) service configuration and set its "CallByValue" attribute to "false".
The Naming configuration file is $JBOSS_HOME/server/default/deploy/naming-service.xml for an installer-generated JBoss configuration and $JBOSS_HOME/server/conf/jboss-service.xml (the JNDI section, search for "jboss:service=Naming") for a basic installation.
*1.2 Deploy the EJB jar *
Copy your EJB jar in the server's deployment directory.
A successful deployment generates log output similar to:
21:29:19,281 INFO [EJBDeployer] Deployed: file:/C:/work/src/jboss-4.0.4.GA-src/build/output/ jboss-4.0.4.GA/server/test/tmp/deploy/tmp27384mdb.ear-contents/mdb.jar
2. Remote JBoss Messaging instance
(Note: This procedure applies not only to an MDB that needs to access a remote messaging service, but also an EAR containing a jms client, or a WAR)
The key point is to include your MDB jar in an enterprise archive file that provides scoping and contains the dependency libraries.
2.1 Make sure the MDB JAR manifest contains required dependencies
The Class-Path of your JAR's manifest must contain the path to the required dependencies. A MANIFEST.MF example follows:
Class-Path: lib/jboss-messaging.jar lib/jboss-aop.jar lib/jboss-remoting.jar lib/jboss-serialization.jar lib/javassist.jar lib/trove.jar lib/jboss-common-softvaluehashmap.jar
2.2 Create a scoped EAR
The EAR must be scoped. Assuming that your EJB JAR name is mdb.jar, the J2EE and JBoss-specific deployment descriptors are:
<?xml version="1.0" encoding="UTF-8"?> <application> <display-name>MDB</display-name> <module> <ejb>mdb.jar</ejb> </module> </application>
<?xml version="1.0" encoding="UTF-8"?> <jboss-app> <loader-repository>mydomain:loader=MyRepository <loader-repository-config>java2ParentDelegaton=false</loader-repository-config> </loader-repository> </jboss-app>
When creating the EAR, make sure you include the corresponding dependencies (lib/jboss-messaging.jar, lib/jboss-aop.jar, lib/jboss-remoting.jar, etc.) so they will be available from the "lib" subdirectory of the archive.
DO NOT include jboss-messaging-client.jar, because doing so will lead to scoping conflicts.
The structure of your EAR should be similar to
+-META-INF | | | +-- MANIFEST.MF | +-- application.xml | +-- jboss-app.xml | +---lib | | | +-- jboss-messaging.jar | +-- jboss-aop.jar | +-- jboss-remoting.jar | +-- jboss-serialization.jar | +-- javassist.jar | +-- trove.jar | +-- jboss-common-softvaluehashmap.jar | +-- mdb.jar | +-- MANIFEST.MF: Class-Path: lib/jboss-messaging.jar ... +-- ...
At the time of the writing (JBoss Messaging 1.0.1.CR4), various dependency libraries need to be individually added to the EAR archive. As a convenience, future Messaging releases will contain an aggregated library JAR that includes all dependencies. The aggregated library will be shipped with the release and it will be named most likely mdb-container-support.jar.
2.3 Deploy the EAR
Copy your EAR in the server's deployment directory.
A successful deployment generates log output similar to:
21:29:16,125 INFO [EARDeployer] Init J2EE application: file:/C:/work/src/jboss-4.0.4.GA-src/build/output/jboss-4.0.4.GA/server/test/ deploy/mdb.ear 21:29:16,890 INFO [EjbModule] Deploying MDB 21:29:19,281 INFO [EJBDeployer] Deployed: file:/C:/work/src/jboss-4.0.4.GA-src/build/output/jboss-4.0.4.GA/server/test/ tmp/deploy/tmp27384mdb.ear-contents/mdb.jar 21:29:19,328 INFO [EARDeployer] Started J2EE application: file:/C:/work/src/jboss-4.0.4.GA-src/build/output/jboss-4.0.4.GA/server/test/ deploy/mdb.ear
3. Remote JBoss Messaging instance (Alternate method)
If you plan to deploy a large number of MDBs, it doesn't make practical sense to scope Messaging libraries individually with each deployment. That would lead to a unnecessarily large memory foot print. An alternative method of deploying a scoped MDB is to deploy a "dummy" scoped service that includes all required dependencies, and then deploy your MDBs in the same class loading domain.
Here's the procedure:
Create a scoped SAR:
Create a scoped service archive (SAR) file with all the dependencies as mentioned earlier. For example, the following ant target creates a SAR file with the required dependencies
<target name="simple-mdb-dependencies-sar"> <jar destfile="./output/lib/simple-mdb-dependencies.sar"> <fileset dir="./etc/simplemdbdependencies"> <include name="META-INF/jboss-service.xml" ></include> </fileset> <fileset dir="./lib"> <include name="jboss-messaging.jar" ></include> <include name="jboss-remoting.jar" ></include> <include name="jboss-aop.jar" ></include> <include name="javassist.jar" ></include> <include name="trove.jar" ></include> <include name="jboss-common-softvaluehashmap.jar" ></include> <include name="jboss-serialization.jar" ></include> </fileset> </jar> </target>
Make sure you have the scoping information in META-INF/jboss-service.xml. For example, I've created a scoping domain remotejms:loader=RemoteJMSRepository:
<?xml version="1.0" encoding="UTF-8"?> <!-- Scoped Remote JMS Server SAR deployment descriptor. --> <server> <loader-repository>remotejms:loader=RemoteJMSRepository <loader-repository-config>java2ParentDelegaton=false</loader-repository-config> </loader-repository> </server>
Once you create the SAR, deploy the exploded version to your server.
Create a scoped EAR:
Now that you have a scoped domain, utilize that to deploy the MDBs in that scope.
Create an EAR file as usual with the following artifacts:
+-my-ejb.ear | +-- MANIFEST.MF //no classpath mentioned in this manifest +-- application.xml //ejb module info defined +-- jboss-app.xml // define your scoped domain here | +----+simple-mdb.jar | +-- ejb-jar.xml +-- jboss.xml +-- MANIFEST.MF(with Class-Path: jboss-common-softvaluehashmap.jar,trove.jar,javassist.jar,jboss-aop.jar, jboss-messaging.jar,jboss-remoting.jar,jboss-serialization.jar)
The jboss-app.xml defines the scoping:
<jboss-app> <loader-repository>remotejms:loader=RemoteJMSRepository <loader-repository-config>java2ParentDelegaton=false</loader-repository-config> </loader-repository> </jboss-app>
Deploy the my-ejb.ear and it should start up without any complains:
16:22:14,850 INFO [EARDeployer] Started J2EE application: file:/sandbox/konmad-sbox/dev/platform/jboss-with-tx-and-msg/jboss-4.0.3SP1/server/ default/deploy/simple-mdb.ear