Chapter 7. JBoss EJB 3.0 jboss.xml deployment descriptor

Jboss supports several vendor specific extensions EJB 3.0. The extensions are specified either as source code annotations or through the jboss.xml deployment descriptor. The chapter discusses the tags and options of the EJB 3.0 jboss.xml deployment descriptor.

7.1. Bean extensions

JBoss offers the capability to create additional Service and Consumer/Producer bean types.

7.1.1. Service

JBoss offers the capability to create services through the @Service annotation or through the jboss.xml deployment descriptor. They are singleton beans and are not pooled. Service beans can expose both local and remote interfaces so they can be accessed from java clients. When different clients access the interfaces for Service beans, all clients will be accessing the same instance on the server. Below is an example of a jboss.xml deployment descriptor that specifies a Service.

The implementing class is specified by the ejb-class tag. Local and remote interfaces are specified with the local and remote tags, respectively. JNDI bindings are specified through the jndi-name and the local-jndi-name tags.

A Service bean can also implement a management interface, which wraps the MBean and installs the Service as an MBean on the MBean server. The management interface is specified by the management tag. The management interface can support the standard lifecycle management of JBoss JMX.

When deployed, the bean is assigned a JMX ObjectName in the MBean server. The ObjectName can be explicitly set with the object-name tag. The default is: jboss.j2ee:service=EJB3,name=<Fully qualified name of @Service bean>,type=service.

Here is the example remote interface:

public interface ServiceSixRemote
{
   boolean getCalled();
   void setCalled(boolean called);
   void remoteMethod();
}
            

Here is the example local interface:

public interface ServiceSixLocal
{
   boolean getCalled();
   void setCalled(boolean called);
   void localMethod();
}
            

Here is the example management interface:

public interface ServiceSixManagement
{
   String jmxOperation(String s);
   String[] jmxOperation(String[] s);
   int getAttribute();
   void setAttribute(int i);
   int getSomeAttr();
   void setSomeAttr(int i);
   int getOtherAttr();
   void setOtherAttr(int i);
   void setWriteOnly(int i);
   int getReadOnly();

   void create() throws Exception;
   void start() throws Exception;
   void stop();
   void destroy();
}
            

Here is the implementing Service bean class:

public class ServiceSix implements ServiceSixLocal, ServiceSixRemote, ServiceSixManagement
{
   boolean called;
   
   int localMethodCalls;
   int remoteMethodCalls;
   int jmxAttribute;
   int someJmxAttribute;
   int otherJmxAttribute;
   int readWriteOnlyAttribute;


   public boolean getCalled()
   {
      return called;
   }

   public void setCalled(boolean called)
   {
      this.called = called;
   }

   public void localMethod()
   {
      called = true;
   }

   public void remoteMethod()
   {
      called = true;
   }
   
   public String jmxOperation(String s)
   {
      return "x" + s + "x";
   }

   public String[] jmxOperation(String[] s)
   {
      return s;
   }

   public int getAttribute()
   {
      return jmxAttribute;
   }

   public void setAttribute(int i)
   {
      jmxAttribute = i;
   }

   public int getSomeAttr()
   {
      return someJmxAttribute;
   }

   public void setSomeAttr(int i)
   {
      someJmxAttribute = i;
   }

   public int getOtherAttr()
   {
      return otherJmxAttribute;
   }

   public void setOtherAttr(int i)
   {
      otherJmxAttribute = i;
   }

   public void setWriteOnly(int i)
   {
      readWriteOnlyAttribute = i;
   }

   public int getReadOnly()
   {
      return readWriteOnlyAttribute;
   }


   public void create() throws Exception
   {
   }

   public void start() throws Exception
   {
   }

   public void stop()
   {
   }

   public void destroy()
   {
   }
            

Here is the example deployment descriptor:

<jboss>
   <enterprise-beans>
      <service>
         <ejb-class>org.jboss.ejb3.test.service.ServiceSix</ejb-class>
         <local>org.jboss.ejb3.test.service.ServiceSixLocal</local>
         <remote>org.jboss.ejb3.test.service.ServiceSixRemote</remote>
         <management>org.jboss.ejb3.test.service.ServiceSixManagement</management>
         <jndi-name>serviceSix/remote</jndi-name>
         <local-jndi-name>serviceSix/local</local-jndi-name>
      </service>
   </enterprise-beans>
</jboss>

7.1.2. Consumer/Producer

JBoss offers the capability to create message producers and consumers through the @Producer and @Consumer annotations or through the jboss.xml deployment descriptor. The Consumer class is specified using the consumer and ejb-class tags. The destination and destination type are specified in the destination and destination-type tags. The Producer interface is specified by the producer tag. Messages are created and sent to the configured destination when one of the Producer methods is called. A Consumer is configured to listen on a destination and when a message arrives, the current message is set in the implementing Consumer bean based on the current-message tag.

Here is the example for the remote and Producer interfaces:

public interface DeploymentDescriptorQueueTestRemote
{
   void method1(String msg, int num);

   void method2(String msg, float num);
}
            

Here is the example for the implementing Consumer/Producer bean class

public class DeploymentDescriptorQueueTestConsumer implements DeploymentDescriptorQueueTestRemote
{
   Message currentMessage;

   private Message setterMessage;

   void setMessage(Message msg)
   {
      setterMessage = msg;
   }

   public void method1(String msg, int num)
   {
      TestStatusBean.queueRan = "method1";
      TestStatusBean.fieldMessage = currentMessage != null;
      TestStatusBean.setterMessage = setterMessage != null;

      System.out.println("method1(" + msg + ", " + num + ")");
   }

   public void method2(String msg, float num)
   {
      TestStatusBean.queueRan = "method2";

      TestStatusBean.fieldMessage = currentMessage != null;
      TestStatusBean.setterMessage = setterMessage != null;

      System.out.println("method2(" + msg + ", " + num + ")");
   }
}
            

Here is an example code snippet for a Consumer/Producer client. When the tester.method# methods are called, the current message is set in the Consumer bean.

 public void testDeploymentDescriptorQueue() throws Exception
   {
     
      DeploymentDescriptorQueueTestRemote tester = (DeploymentDescriptorQueueTestRemote) getInitialContext().lookup(DeploymentDescriptorQueueTestRemote.class.getName());
      ProducerManager manager = (ProducerManager) ((ProducerObject) tester).getProducerManager();
      manager.connect();
      try
      {
         tester.method1("testQueue", 5);

         tester.method2("testQueue", 5.5F);
      }
      finally
      {
         manager.close();
      }
   }
            

Here is the example deployment descriptor:

<jboss>
   <enterprise-beans>
      <consumer>
         <ejb-name>DeploymentDescriptorQueueTestConsumer</ejb-name>
         <ejb-class>org.jboss.ejb3.test.consumer.DeploymentDescriptorQueueTestConsumer</ejb-class>
         <destination>queue/consumertest</destination>
         <destination-type>javax.jms.Queue</destination-type>
         <producer>org.jboss.ejb3.test.consumer.DeploymentDescriptorQueueTestRemote</producer>
         <current-message>
            <method>
               <method-name>currentMessage</method-name>
            </method>
            <method>
               <method-name>setMessage</method-name>
            </method>
         </current-message>
         <message-properties>
            <method>
               <method-name>method2</method-name>
            </method>
            <delivery>NonPersistent</delivery>
         </message-properties>
      </consumer>
   </enterprise-beans>
</jboss>