Version 15

    Embedded JBoss and Tomcat


    Embedded JBoss can be run inside a standalone Tomcat distribution.  You can deploy components just as you traditionally do in the JBoss application, or you can have Embedded JBoss scan a web-app deployment.





    Configuring Tomcat To Initialize Embedded JBoss


    Embedded JBoss is bootstrapped by a Tomcat Listener configured in conf/server.xml of your tomcat distribution. 


      <Listener className="org.jboss.embedded.tomcat.EmbeddedJBossBootstrapListener" ></Listener>


    This listener should come under the Server element in server.xml.  The position of this listener is important as it must come after other configured listeners.


    <Server port="8005" shutdown="SHUTDOWN">
      <!-- Comment these entries out to disable JMX MBeans support used for the 
           administration web application -->
      <Listener className="org.apache.catalina.core.AprLifecycleListener" ></Listener>
      <Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" ></Listener>
      <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" ></Listener>
      <Listener className="org.apache.catalina.storeconfig.StoreConfigLifecycleListener"></Listener>


      <Listener className="org.jboss.embedded.tomcat.EmbeddedJBossBootstrapListener" ></Listener>





    There are a few ways you can deploy your EJBs, datasources, and other JBoss components into a Tomcat-only environment.  There are advantages and disadvantages to each approach.


    Scanning every WAR by default


    Perhaps the simplest way to deploy your EJBs, datasources, and other JBoss components is to put these .jars and files directly in the WEB-INF/lib and WEB-INF/classes directories of your deployed web apps.  You can have Embedded JBoss automatically scan each and every web app Tomcat deploys for JBoss components.  To do this you modify the default context configuration file of tomcat located in apache-tomcat/conf/context.xml and add the Embedded JBoss org.jboss.embedded.tomcat.WebinfScanner listener class.



    <!-- The contents of this file will be loaded for each web application -->
        <!-- Default set of monitored resources -->
        <!-- Uncomment this to disable session persistence across Tomcat restarts -->
        <Manager pathname="" ></Manager>

      <Listener className="org.jboss.embedded.tomcat.WebinfScanner" ></Listener>



    The advantage of this approach is that you do not have to put any special configuration in your WAR files to deploy JBoss components.  The disadvantage is that deployment time may slow down as deployers like the EJB3 container need to scan every .jar file for classes annotated with EJB3 annotations.


    Scanning individual .jars and files in a WAR file


    Deployers like EJB3 have to scan each and every .jar file for classes that are annotated to see if it needs to process that particular archive.  This can be time consuming.  Therefore you might want to have a more fine-grained approach to deployment.  Embedded JBoss provides a simple ServletContextListener which will only deploy WAR resources that you specify as parameters.  You would need to modify the WEB-INF/web.xml file of your web app.


          <param-value>/WEB-INF/lib/titan-ejbs.jar, /WEB-INF/classes/oracle-ds.xml</param-value>


    This deployment would ask Embedded JBoss to only deploy the titan-ejbs.jar file located in WEB-INF/lib of the web app as well as the oracle-ds.xml file in WEB-INF/classes.


    Using the deploy/ directory


    Just like JBoss AS, you can place files within a deploy/ directory and they will be automatically deployed by the bootstrapping mechanism of Embedded JBoss.  By default, this directory lies within this path in the tomcat distribution:




    There are some differences though with this directory's behavior and that of the JBoss application server.  JARS ARE NOT ADDED TO CLASSPATH.  Tomcat expects jars to be in common/lib.  It is important to remember that Embedded JBoss gives total control over classloading and the classpath to you, the application developer.  Embedded JBoss will try and deploy jar file types within the deploy/ directory but unless you have added that jar file to your classpath manually, Embedded JBoss will not add the jar automatically to your classpath.  Again, this is because it is up to the app developer to decide this.


    Therefore, it is wise to only put non-jar deployments like -ds.xml files in the deploy directory.


    Deploying a JCA resource archive (.rar) file


    Embedded JBoss does support deploying .rar files, but it will not add nested jars into your application's classpath.  So, what you have to do is unpackage the .rar and move any nested jar files into tomcat's lib directory.


    Deploying all .jar files in the common/lib directory

    You may want Tomcat to deploy things like EJBs that are packaged in .jar files in the common/lib directory.  You can have Embedded JBoss try to deploy all of these .jar files.  To do this you must edit the common/classes/conf/bootstrap-beans.xml file and a new DeploymentScanner.  Make this edit at the bottom of bootstrap-beans.xml as follows:


       <bean name="ResourcesToDeploy4" class="org.jboss.embedded.DeploymentScanner">
          <property name="filter">
             <inject bean="DeploymentFilter"></inject>
          <property name="mainDeployer">
             <inject bean="MainDeployer"></inject>
          <property name="kernel">
             <inject bean="jboss.kernel:service=Kernel"></inject>
          <property name="directoriesByResource">
             <list elementClass="java.lang.String">


    Deploying individual .jar files in the common/lib directory

    Instead of scanning all .jar files in common/lib you may only want to scan individual .jar files.  For example, let's say we had a titan-ejbs.jar file in our common/lib directory.  We'd edit bootstrap-beans.xml as follows:


       <bean name="ResourcesToDeploy4" class="org.jboss.embedded.DeploymentScanner">
          <property name="mainDeployer">
             <inject bean="MainDeployer"></inject>
          <property name="kernel">
             <inject bean="jboss.kernel:service=Kernel"></inject>
          <property name="filesByResource">
             <list elementClass="java.lang.String">


    Multiple Seam applications in the same Tomcat server


    Currently only one Seam application is supported per tomcat. See JBSEAM-1663 and JBOSS Forums multiple seam apps on tomcat (w/ embeded jboss)




    Embedded JBoss components like connection pooling, EJB, JPA, and transactions make extensive use of JNDI to publish services.  Embedded JBoss overrides Tomcat's JNDI implementation by layering itself on top of Tomcat's JNDI instantiation.  There are a few reasons for this:


    1. To avoid having to declare each and every one of these services within server.xml

    2. To allow seemeless integration of the java:comp namespace between web apps and EJBs.

    3. Tomcat's JNDI implementation has a few critical bugs in it that hamper some JBoss components ability to work

    4. We want to provide the option for you of remoting EJBs and other services that can be remotely looked up