[jboss-cvs] JBossAS SVN: r82605 - in projects/ejb3/trunk/docs/tutorial/guide/en: modules and 1 other directory.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Mon Jan 5 02:49:01 EST 2009


Author: jaikiran
Date: 2009-01-05 02:49:00 -0500 (Mon, 05 Jan 2009)
New Revision: 82605

Added:
   projects/ejb3/trunk/docs/tutorial/guide/en/modules/embeddable.xml
   projects/ejb3/trunk/docs/tutorial/guide/en/modules/entity.xml
   projects/ejb3/trunk/docs/tutorial/guide/en/modules/extended_pc.xml
   projects/ejb3/trunk/docs/tutorial/guide/en/modules/injection.xml
   projects/ejb3/trunk/docs/tutorial/guide/en/modules/interceptor.xml
   projects/ejb3/trunk/docs/tutorial/guide/en/modules/jndibinding.xml
   projects/ejb3/trunk/docs/tutorial/guide/en/modules/mdb.xml
   projects/ejb3/trunk/docs/tutorial/guide/en/modules/mdb_deployment_descriptor.xml
Modified:
   projects/ejb3/trunk/docs/tutorial/guide/en/master.xml
   projects/ejb3/trunk/docs/tutorial/guide/en/modules/todo.xml
Log:
Added more tutorials to the guide

Modified: projects/ejb3/trunk/docs/tutorial/guide/en/master.xml
===================================================================
--- projects/ejb3/trunk/docs/tutorial/guide/en/master.xml	2009-01-05 04:12:59 UTC (rev 82604)
+++ projects/ejb3/trunk/docs/tutorial/guide/en/master.xml	2009-01-05 07:49:00 UTC (rev 82605)
@@ -6,6 +6,12 @@
 <!ENTITY blob          SYSTEM "modules/blob.xml">
 <!ENTITY callbacks          SYSTEM "modules/callbacks.xml">
 <!ENTITY composite          SYSTEM "modules/composite.xml">
+<!ENTITY embeddable          SYSTEM "modules/embeddable.xml">
+<!ENTITY entity          SYSTEM "modules/entity.xml">
+<!ENTITY extended_pc          SYSTEM "modules/extended_pc.xml">
+<!ENTITY injection          SYSTEM "modules/injection.xml">
+<!ENTITY interceptor          SYSTEM "modules/interceptor.xml">
+<!ENTITY jndibinding          SYSTEM "modules/jndibinding.xml">
 <!ENTITY todo          SYSTEM "modules/todo.xml">
 ]>
 <book lang="en">
@@ -19,5 +25,5 @@
     <title>Target Audience</title>
     <para>This tutorial is meant for EJB3 application developers on JBoss Application Server. The tutorial walks you through the EJB 3.0 features and how they deploy to JBoss.  Please check the <xref linkend="Installation">install guide</xref> for system requirements.</para>
   </preface>
-&installing;&stateless;&stateful;&blob;&callbacks;&composite;&todo;
+&installing;&stateless;&stateful;&blob;&callbacks;&composite;&embeddable;&entity;&extended_pc;&injection;&interceptor;&jndibinding;&todo;
 </book>

Added: projects/ejb3/trunk/docs/tutorial/guide/en/modules/embeddable.xml
===================================================================
--- projects/ejb3/trunk/docs/tutorial/guide/en/modules/embeddable.xml	                        (rev 0)
+++ projects/ejb3/trunk/docs/tutorial/guide/en/modules/embeddable.xml	2009-01-05 07:49:00 UTC (rev 82605)
@@ -0,0 +1,89 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<chapter id="Embeddable Objects in EJB3 Entities">
+	<title>Introduction to embedding objects in EJB3 entities</title>
+	<para>
+		The EJB3 specification allows you to embed plain Java objects within your entities
+		and map the properties of this embedded value object to columns within the entity's
+		table.
+	</para>
+	
+	<para>
+	The <literal>org.jboss.tutorial.embeddable.bean.Customer</literal> entity encapsulates the name of the customer
+	in the <literal>org.jboss.tutorial.embeddable.bean.Name</literal> value object. The
+	<literal>org.jboss.tutorial.embeddable.bean.Name</literal> value object must be tagged with the <literal>@Embeddable</literal>
+	annotation.
+	
+	<programlisting>
+	<![CDATA[
+ at Embeddable
+public class Name implements java.io.Serializable
+	]]>
+	</programlisting>
+	
+	The properties of Name must then be mapped to columns within Customer's table.
+	
+	<programlisting>
+	<![CDATA[
+ at Embedded
+ at AttributeOverrides({
+   @AttributeOverride(name = "first", column = {@Column(name = "FIRST_NAME")}),
+   @AttributeOverride(name = "last", column = {@Column(name = "LAST_NAME")})
+})
+public Name getName()
+{
+   return name;
+}	
+	]]>	
+	</programlisting>
+	</para>
+
+	<sect5>
+Building and Running
+	</sect5>
+		
+		<note>
+			<para>
+	To build and run the example, make sure you have installed JBoss 5.x. 
+	See the <xref linkend="JBossAS5">installation section</xref> for details.
+			</para>
+		</note>
+
+	<sect5>
+Ant Users:
+	</sect5>
+		<para>
+		Make sure your JBossAS-5.x is running
+		</para>
+	<programlisting>
+	<![CDATA[
+$ ant
+$ ant run
+
+run:
+     [java] Create Bill Burke and Monica Smith
+     [java] Bill and Monica get married
+     [java] Get all the Burkes
+     [java] There are now 2 Burkes
+     ]]>
+	</programlisting>
+
+	<sect5>
+Maven Users: <xref linkend="Maven_Users_TODO">TODO</xref>
+	</sect5>
+	
+	<programlisting>
+$ mvn clean install
+	</programlisting>
+	
+	<sect5>
+View the tables and rows:
+	</sect5>
+	<para>
+		You can view the tables created by JBoss by going to the 
+		<ulink url="http://localhost:8080/jmx-console/HtmlAdaptor?action=inspectMBean&amp;name=jboss%3Aservice%3DHypersonic%2Cdatabase%3DlocalDB">Hypersonic Service</ulink>,
+		scrolling down to the <literal>startDatabaseManager</literal> button and clicking it.  
+		A Hypersonic SQL window will be minimized, but you can open it up to look at the tables and do queries.
+	
+	</para>	
+	
+</chapter>
\ No newline at end of file

Added: projects/ejb3/trunk/docs/tutorial/guide/en/modules/entity.xml
===================================================================
--- projects/ejb3/trunk/docs/tutorial/guide/en/modules/entity.xml	                        (rev 0)
+++ projects/ejb3/trunk/docs/tutorial/guide/en/modules/entity.xml	2009-01-05 07:49:00 UTC (rev 82605)
@@ -0,0 +1,221 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<chapter id="EJB3 Entities">
+	<title>Introduction to Entities in EJB3</title>
+	<para>
+		Entity Beans of EJB2.x have been given a complete overhaul in EJB 3.0.
+		Entity beans (or Entities, as they are now called) are plain Java objects that can be allocated
+		with <literal>new</literal> and attached/detached/reattached to persistence storage.
+		Entities are not remotable and must be accessed through the new <literal>javax.persistence.EntityManager</literal> service.
+		JBoss's EJB 3.0 entity implementation is built on top of Hibernate.
+	</para>
+	
+	<sect5>
+		O/R Mapping :
+	</sect5>
+	<para>
+		First let's look at the example implementation of two related Entities. 
+		<literal>org.jboss.tutorial.entity.bean.Order</literal> and <literal>org.jboss.tutorial.entity.bean.LineItem</literal>.
+		These two entities form a one-to-many relationship.
+	</para>
+	
+	<para>
+		The persistence determines the persistent properties by looking for all getter/setter method pairs.
+		By default, all getter/setter methods will be treated as persistence properties.
+	</para>
+	
+	<para>	
+		Defining an Entity is easy. First, annotate the class as an <literal>@Entity</literal>. In the minimum, you must at
+		least define a primary key field using the <literal>@Id</literal> annotation.
+		
+		<programlisting>
+		<![CDATA[
+ at Id @GeneratedValue
+public int getId()
+{
+   return id;
+}		
+		]]>
+		</programlisting>
+		<note>
+			<para>
+				Annotations must be defined on the getter method or on the field. However, you cannot have a mix of annotations
+				on the field and on the methods. The following example where we are mapping the <literal>name</literal> through
+				the field and mapping the <literal>age</literal> through the method is not allowed:
+				
+				<programlisting>
+					<![CDATA[
+ at Entity
+public class Employee implements java.io.Serializable
+{
+
+	@Id
+	@GeneratedValue(strategy=GenerationType.AUTO)
+	private long id;
+	
+	@Column (name="NAME")
+	private String name;
+	
+	private int age;
+	
+	@Column (name="AGE")
+	public int getAge()
+	{
+		return this.age
+	}
+	
+	public String getName()
+	{
+	
+	}
+	// other getter/setters
+}
+					]]>
+				</programlisting> 
+			</para>
+			
+		</note>	
+		
+		The <literal>@Id</literal> annotation tells the container that <literal>id</literal> is the primary key property.
+		The <literal>@GeneratedValue</literal> tells that it should be automatically generated by the container.
+		The table name is specified using the <literal>@Table</literal> annotation
+		
+		<programlisting>
+		<![CDATA[
+ at Table(name = "PURCHASE_ORDER")
+		]]>
+		</programlisting>
+		
+		If the table name isn't specified it defaults to the simple name of the class. For instance, the LineItem entity would be 
+		mapped to the LINEITEM table.
+	</para>
+	
+	<sect5>
+		One to Many Relationship :
+	</sect5>
+	<para>
+		The Order bean also defines a one to many relationship.
+		
+		<programlisting>
+			<![CDATA[
+ at OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy="order")
+public Collection<LineItem> getLineItems()
+{
+   return lineItems;
+}			
+			]]>
+		</programlisting>
+		Generics must be used so that the container can determine what the entity Order is related to.
+		<para>
+			<literal>CascadeType.ALL</literal> specifies that when an Order is created, any LineItems held in the <literal>lineItems</literal>
+			collection will be created as well (<literal>CascadeType.PERSIST</literal>). If the Order is deleted from persistence storage,
+			all related LineItems will be deleted (<literal>CascadeType.REMOVE</literal>). If an Order instance is reattached to persistence
+			storage, any changes to the LineItems collection will be merged with persistence storage (<literal>CascadeType.MERGE</literal>).
+		</para>
+		
+		<para>	
+			<literal>FetchType.EAGER</literal> specifies that when the Order is loaded whether or not to pre-fetch the relationship as well.
+			If you want the LineItems to be loaded on demand, then specify <literal>FetchType.LAZY</literal>.
+		</para>
+		
+		<para>
+			The <literal>mappedBy</literal> attribute specifies that this is a bi-directional relationship that is managed by the order property
+			on the LineItem entity.
+		</para>
+		
+	</para>
+	
+	<sect5>
+		Many to One Relationship :
+	</sect5>
+	<para>
+		<programlisting>
+			<![CDATA[
+ at ManyToOne
+ at JoinColumn(name = "order_id")
+public Order getOrder()
+{
+   return order;
+}	
+		]]>
+		</programlisting>
+		
+		The <literal>@JoinColumn</literal> specifies the foreign key column within the LineItem table.
+		
+	</para>
+	
+	<sect5>
+		EntityManager :
+	</sect5>
+	<para>
+		The <literal>org.jboss.tutorial.entity.bean.ShoppingCartBean</literal> allocates and stores all instances
+		of Orders and LineItems. If you look at the example you can see that ShoppingCart interacts with Order as a plain Java object.
+		It allocates it with <literal>new</literal>. It can pass the Order back to the client. The <literal>checkout()</literal>
+		method actually stores it with persistence storage by using the required EntityManager service.
+
+		The EntityManager service is injected using field injection and the <literal>@PersistenceContext</literal> annotation.
+		<programlisting>
+			<![CDATA[
+ at PersistenceContext
+private EntityManager manager;
+			
+			]]>
+		</programlisting>	
+		
+		The EntityManager is central to EJB 3.0 as there are no homes. The EntityManager is used to do querying, creating,
+		find by primary key, and removal of entities in EJB3.
+	</para>
+	
+	<sect5>
+Building and Running
+	</sect5>
+		
+		<note>
+			<para>
+	To build and run the example, make sure you have installed JBoss 5.x. 
+	See the <xref linkend="JBossAS5">installation section</xref> for details.
+			</para>
+		</note>
+
+	<sect5>
+Ant Users:
+	</sect5>
+		<para>
+		Make sure your JBossAS-5.x is running
+		</para>
+	<programlisting>
+	<![CDATA[
+$ ant
+$ ant run
+
+run:
+     [java] Buying 2 memory sticks
+     [java] Buying a laptop
+     [java] Print cart:
+     [java] Total: $3000.0
+     [java] 2     Memory stick     1000.0
+     [java] 1     Laptop     2000.0
+     [java] Checkout
+     
+     ]]>
+	</programlisting>
+
+	<sect5>
+Maven Users: <xref linkend="Maven_Users_TODO">TODO</xref>
+	</sect5>
+	
+	<programlisting>
+$ mvn clean install
+	</programlisting>
+	
+	<sect5>
+View the tables and rows:
+	</sect5>
+	<para>
+		You can view the tables created by JBoss by going to the 
+		<ulink url="http://localhost:8080/jmx-console/HtmlAdaptor?action=inspectMBean&amp;name=jboss%3Aservice%3DHypersonic%2Cdatabase%3DlocalDB">Hypersonic Service</ulink>,
+		scrolling down to the <literal>startDatabaseManager</literal> button and clicking it.  
+		A Hypersonic SQL window will be minimized, but you can open it up to look at the tables and do queries.
+	
+	</para>
+	
+</chapter>
\ No newline at end of file

Added: projects/ejb3/trunk/docs/tutorial/guide/en/modules/extended_pc.xml
===================================================================
--- projects/ejb3/trunk/docs/tutorial/guide/en/modules/extended_pc.xml	                        (rev 0)
+++ projects/ejb3/trunk/docs/tutorial/guide/en/modules/extended_pc.xml	2009-01-05 07:49:00 UTC (rev 82605)
@@ -0,0 +1,163 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<chapter id="Extended Persistence Contexts">
+	<title>Introduction to Extended Persistence Contexts</title>
+	<para>
+		Usually, an EntityManager in JBoss EJB 3.0 lives and dies within a JTA transaction. Once the transaction is finished,
+		all persistent objects are detached from the EntityManager and are no longer managed.
+		Any local caching the EntityManager instance had done is lost. JBoss EJB 3.0 allows you to define long-living EntityManagers
+		that live beyond the scope of a JTA transaction. This is called an Extended Persistence Context.
+
+		When you specify that an injected EntityManager is an extended persistence context, all object instances remain managed.
+		
+	</para>
+	
+	<para>
+		Extended persistence contexts can only be used within Stateful session beans. Take a look at 
+		<literal>org.jboss.tutorial.extended.bean.ShoppingCartBean</literal>.
+		
+		<programlisting>
+			<![CDATA[
+ at Stateful
+ at Remote(ShoppingCart.class)
+public class ShoppingCartBean implements ShoppingCart
+{
+   @PersistenceContext(type=PersistenceContextType.EXTENDED)
+   EntityManager em;
+
+   @EJB StatelessLocal stateless;
+
+   private Customer customer;
+
+   public long createCustomer()
+   {
+      customer = new Customer();
+      customer.setName("William");
+      em.persist(customer);
+      return customer.getId();
+   }
+
+   public void update()
+   {
+      customer.setName("Bill");
+   }
+...
+}
+			
+			]]>
+		</programlisting>
+		
+		To inject an extended persistence context, you use the <literal>type()</literal> attribute and set it to <literal>EXTENDED</literal>.
+		If you look at the <literal>createCustomer()</literal> method you notice that it is persisting a <literal>Customer</literal> object
+		and storing a reference to that	created object within a member variable of the stateful bean. When the update() method is called,
+		you see that the customer's state is modified. Since the entity manager used is EXTENDED, the customer member variable remains
+		managed by the entitymanager and the modified state will be synchronized with the database.
+		
+	</para>
+	
+	<sect5>
+		Conversations :
+	</sect5>
+	
+	<para>
+		An even more interesting use case is when you combine extended persistence contexts with non-transactional methods. 
+		If you interact with an extended persistence context outside of a transaction, the inserts, updates, and deletes
+		will be queued until you access the persistence context within a transaction. This means that any persist(), merge(), 
+		or remove() method you call will not actually result in a JDBC execution and thus an update of the database until
+		you manually call EntityManager.flush().
+		<para>
+			Why is this useful? Consider the usecase of a Setup Wizard on a website.  The Wizard has seven steps, seven web pages to enter
+			stuff in.  It is extremely unwise to have a JTA transaction that spans multiple http requests, yet you do not want to commit
+			anything to the database until all steps are complete.  Your code can interact with the EntityManager as it wants and you
+			do not have to worry about updates or writing a lot of gluecode in your application to do all the entity manager's work in the
+			final step of the wizard.  Efficient and highly performant. Because the managed persistent objects remain attached to the 
+			persistent context, all optmistic versioning checks can also be maintained within the application transaction. 
+			Here's an example on how to do this.
+			
+			<programlisting>
+				<![CDATA[
+ at Stateful
+ at Remote(ShoppingCart.class)
+public class ShoppingCartBean implements ShoppingCart
+{
+   @PersistenceContext(type=PersistenceContextType.EXTENDED)
+   EntityManager em;
+
+   @EJB StatelessLocal stateless;
+
+   private Customer customer;
+
+   public long createCustomer()
+   {
+      customer = new Customer();
+      customer.setName("William");
+      em.persist(customer);
+      return customer.getId();
+   }
+
+   @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
+   public void never()
+   {
+      customer.setName("Bob");
+   }
+
+
+
+   @Remove
+   public void checkout()
+   {
+   }
+}
+				
+				]]>
+			</programlisting>
+		</para>
+		Calling the never() method will update the managed customer object reference, but will not result in a database update until
+		checkout() is called. The spec requires that any time you invoke a transactional method of a stateful bean, 
+		that the EntityManager join the transaction. Therefore, our never() update will be committed at the end of the checkout() method
+		(which by default has the REQUIRED trasaction attribute).
+		
+	</para>
+	
+	<sect5>
+Building and Running
+	</sect5>
+		
+		<note>
+			<para>
+	To build and run the example, make sure you have installed JBoss 5.x. 
+	See the <xref linkend="JBossAS5">installation section</xref> for details.
+			</para>
+		</note>
+
+	<sect5>
+Ant Users:
+	</sect5>
+		<para>
+		Make sure your JBossAS-5.x is running
+		</para>
+	<programlisting>
+	<![CDATA[
+$ ant
+$ ant run
+
+run:
+     [java] Created customer: William
+     [java] Customer's name should still be William as pc was not yet flushed:  Customer.getName() == William
+     [java] Now that the pc has been flushed name should be 'Bob': Customer.getName() == Bob
+     [java] Created customer: William
+     [java] ShoppingCartBean.customer should stay managed because we're in an extended PC: Customer.getName() == Bill
+     [java] Extended persistence contexts are propagated to nested EJB calls: Customer.getName() == Bill Jr.
+     
+     ]]>
+	</programlisting>
+
+	<sect5>
+Maven Users: <xref linkend="Maven_Users_TODO">TODO</xref>
+	</sect5>
+	
+	<programlisting>
+$ mvn clean install
+	</programlisting>
+	
+	
+</chapter>
\ No newline at end of file

Added: projects/ejb3/trunk/docs/tutorial/guide/en/modules/injection.xml
===================================================================
--- projects/ejb3/trunk/docs/tutorial/guide/en/modules/injection.xml	                        (rev 0)
+++ projects/ejb3/trunk/docs/tutorial/guide/en/modules/injection.xml	2009-01-05 07:49:00 UTC (rev 82605)
@@ -0,0 +1,127 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<chapter id="Dependency Injection">
+	<title>Introduction to dependency injection</title>
+	<para>
+		To facilitate test driven development, the EJB 3.0 specification allows you to use annotations to inject 
+		dependencies through annotations on fields or setter methods. Instead of complicated XML ejb-refs or resource refs,
+		you can use the <literal>@EJB</literal> and <literal>@Resource</literal> annotations to set the value of a 
+		field or to call a setter method within your session bean with anything registered within JNDI.
+		You can use the <literal>@EJB</literal> annotation to inject EJB references and <literal>@Resource</literal> to access datasources.
+	</para>
+	
+	<para>
+		Open up <literal>org.jboss.tutorial.injection.bean.ShoppingCartBean</literal>.
+		ShoppingCartBean uses the Calculator stateless session EJB to do calculations. The example shows two ways to get access 
+		to the Calculator EJB.  One is:
+		
+		<programlisting>
+			<![CDATA[
+ at EJB
+private Calculator calculator;			
+			]]>
+		</programlisting>
+		
+		When the ShoppingCartBean instance is created, the EJB container will set the calculator field using the jndiName
+		of that particular referenced EJB.
+	</para>
+	
+	<para>	
+		You are not limited to injecting dependencies on fields. You can also use @EJB on a setter method. The below example from 
+		ShoppingCartBean uses the <literal>@EJB</literal> annotation to inject the reference to the Calculator session bean:
+		
+		<programlisting>
+			<![CDATA[
+private Calculator set;
+
+ at EJB(beanName="org.jboss.tutorial.injection.bean.CalculatorBean")
+public void setCalculator(Calculator c)
+{
+   set = c;
+}
+			
+			]]>
+		</programlisting>	
+	</para>
+	
+	<para>
+		The <literal>@javax.annotation.Resource</literal> annotation allows you to inject resources.
+		
+		<programlisting>
+		<![CDATA[
+ at Resource(mappedName="DefaultDS")
+private javax.sql.DataSource ds;
+		]]>		
+		</programlisting>
+		
+		<note>
+			<para>
+				In JBoss, whenever the mappedName() attribute is specified (with @Resource, @EJB), JBoss will use that as the GLOBAL jndi name to look it up.
+			</para>
+		</note>
+		
+		The @Resource annotation is used to inject these singletons as well:
+		
+		<programlisting>
+			<![CDATA[
+ at Resource 
+javax.ejb.SessionContext ctx;
+
+ at Resource 
+javax.ejb.TimerService timer;
+
+ at Resource 
+javax.ejb.UserTransaction ut;
+			
+			]]>
+		</programlisting>
+		
+	</para>
+	
+	<para>
+		<literal>@EJB</literal> and <literal>@Resource</literal> also create an entry within the JNDI ENC of the bean. So, the above @EJB 
+		injection will create an entry for the reference calculator bean under "java:comp/env/ejb/calculator".
+	</para>
+	
+	<sect5>
+Building and Running
+	</sect5>
+		
+		<note>
+			<para>
+	To build and run the example, make sure you have installed JBoss 5.x. 
+	See the <xref linkend="JBossAS5">installation section</xref> for details.
+			</para>
+		</note>
+
+	<sect5>
+Ant Users:
+	</sect5>
+		<para>
+		Make sure your JBossAS-5.x is running
+		</para>
+	<programlisting>
+	<![CDATA[
+$ ant
+$ ant run
+
+run:
+     [java] Buying 1 memory stick
+     [java] Buying another memory stick
+     [java] Buying a laptop
+     [java] Print cart:
+     [java] 2     Memory stick
+     [java] 1     Laptop
+     [java] Checkout
+     
+     ]]>
+	</programlisting>
+
+	<sect5>
+Maven Users: <xref linkend="Maven_Users_TODO">TODO</xref>
+	</sect5>
+	
+	<programlisting>
+$ mvn clean install
+	</programlisting>	
+
+</chapter>
\ No newline at end of file

Added: projects/ejb3/trunk/docs/tutorial/guide/en/modules/interceptor.xml
===================================================================
--- projects/ejb3/trunk/docs/tutorial/guide/en/modules/interceptor.xml	                        (rev 0)
+++ projects/ejb3/trunk/docs/tutorial/guide/en/modules/interceptor.xml	2009-01-05 07:49:00 UTC (rev 82605)
@@ -0,0 +1,978 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<chapter id="EJB3 Interceptors">
+	<title>Introduction to EJB3 Interceptors</title>
+	<para>
+		The EJB 3.0 spec defines the ability to apply custom made interceptors
+		to the business methods
+		of your session and message driven beans. EJB
+		3.0 interceptors take the form of methods annotated with
+		the
+		<literal>@javax.ejb.AroundInvoke</literal>
+		annotation. These methods must have the following signature:
+
+		<programlisting>
+			<![CDATA[
+ at javax.ejb.AroundInvoke
+public Object <Arbitrary method name>(javax.ejb.InvocationContext ctx) throws java.lang.Exception
+						
+			]]>
+		</programlisting>
+
+		<note>
+			<para>
+				You can apply interceptors to JBoss specific @Service and
+				@Consumer beans
+			</para>
+		</note>
+
+		You can either define an interceptor method in the bean class itself,
+		or in separate classes.
+		There can only be one interceptor method per
+		class.
+	</para>
+
+	<sect5>
+		Interceptor method in bean class :	
+	</sect5>
+
+	<para>
+		Take a look at
+		<literal>org.jboss.tutorial.interceptor.bean.EmailMDB
+		</literal>
+		. It contains this method:
+
+		<programlisting>
+			<![CDATA[
+ at AroundInvoke
+public Object mdbInterceptor(InvocationContext ctx) throws Exception
+{
+   System.out.println("*** Intercepting call to EmailMDB.mdbInterceptor()");
+   return ctx.proceed();
+}
+			]]>
+		</programlisting>
+
+		This method will wrap the call to EmailMDB.onMessage(). The call to
+		ctx.proceed() causes the next object in the chain of
+		interceptors to
+		get invoked. At the end of the chain of interceptors, the actual bean
+		method gets called.
+		<para>
+			Similarly
+			<literal>org.jboss.tutorial.interceptor.bean.EmailSystemBean
+			</literal>
+			has a method annotated with
+			<literal>@AroundInvoke</literal>
+
+			<programlisting>
+				<![CDATA[
+ at AroundInvoke
+public Object myBeanInterceptor(InvocationContext ctx) throws Exception
+{
+   if (ctx.getMethod().getName().equals("emailLostPassword"))
+   {
+      System.out.println("*** EmailSystemBean.myBeanInterceptor - username: " + ctx.getParameters()[0]);
+   }
+
+   return ctx.proceed();
+}
+				
+				]]>
+			</programlisting>
+		</para>
+	</para>
+
+	<sect5>
+		External interceptors :
+	</sect5>
+
+	<para>
+		The rest of this example will be looking at adding interceptors
+		external to the bean class, more specifically to
+		<literal>EmailSystemBean</literal>
+		. Interceptors can be bound in three different ways:
+		<itemizedlist mark="opencircle">
+			<listitem>
+				<para>
+					Default
+				</para>
+			</listitem>
+			<listitem>
+				<para>
+					Class level
+				</para>
+			</listitem>
+			<listitem>
+				<para>
+					Method level
+				</para>
+			</listitem>
+		</itemizedlist>
+
+		An external interceptor instance follows the lifecycle of the target
+		bean instance.
+	</para>
+
+	<sect5>
+		Default interceptors :
+	</sect5>
+
+	<para>
+		We will see how class and method-level interceptors can be bound to a
+		bean or a bean's method using annotations or xml.
+		Default interceptors
+		can only be bound via xml. A Default interceptor is an interceptor
+		that is invoked whenever a business method
+		is invoked on any bean
+		within the deployment.
+		<para>
+			<literal>org.jboss.tutorial.interceptor.bean.DefaultInterceptor
+			</literal>
+			defines an
+			<literal>@AroundInvoke</literal>
+			method with the required method signature.
+
+			<programlisting>
+					<![CDATA[
+ at AroundInvoke
+public Object intercept(InvocationContext ctx) throws Exception
+{
+   System.out.println("*** DefaultInterceptor intercepting " + ctx.getMethod().getName());
+   try
+   {
+      return ctx.proceed();
+   }
+   finally
+   {
+      System.out.println("*** DefaultInterceptor exiting");
+   }
+}
+					
+					]]>
+			</programlisting>
+
+			As mentioned, default interceptors can only be applied via xml. In
+			<literal>META-INF/ejb-jar.xml</literal>
+			we have the following:
+
+			<programlisting>
+					<![CDATA[
+<assembly-descriptor>
+ <!-- Default interceptor that will apply to all methods for all beans in deployment -->
+ <interceptor-binding>
+      <ejb-name>*</ejb-name>
+      <interceptor-class>org.jboss.tutorial.interceptor.bean.DefaultInterceptor</interceptor-class>
+   </interceptor-binding>
+   ...
+</assembly-descriptor>
+					
+					]]>
+			</programlisting>
+			
+			Using <literal>*</literal> for the ejb-name says that <literal>DefaultInterceptor</literal> is a default interceptor, 
+			i.e. it should intercept all calls to all beans within the deployment unit. We could have added more 
+			<literal>interceptor-class</literal> entries to bind more interceptors, as shown here:
+			
+			<programlisting>
+				<![CDATA[
+<assembly-descriptor>
+   <!-- Default interceptor that will apply to all methods for all beans in deployment -->
+   <interceptor-binding>
+      <ejb-name>*</ejb-name>
+      <interceptor-class>org.jboss.tutorial.interceptor.bean.DefaultInterceptor</interceptor-class>
+      <interceptor-class>org.jboss.tutorial.interceptor.bean.AnotherInterceptor</interceptor-class>
+   </interceptor-binding>
+   ...
+</assembly-descriptor>
+				
+				]]>
+			</programlisting>
+			In this case <literal>DefaultInterceptor</literal> would be invoked before <literal>AnotherInterceptor</literal>.
+						
+		</para>
+	</para>
+	
+	<sect5>
+		Class-level interceptors :
+	</sect5>
+	
+	<para>
+		Class-level interceptors can be bound using xml or annotations.
+			<sect5>
+				Class-level using annotations :
+			</sect5>
+			<para>
+				<literal>org.jbos.tutorial.interceptor.EmailSystemBean</literal> has been annotated:
+				
+				<programlisting>
+					<![CDATA[
+ at Stateless
+ at Interceptors ({TracingInterceptor.class})
+public class EmailSystemBean
+{
+   ...
+}
+					
+					]]>
+				</programlisting>
+				This says that the <literal>@AroundInvoke</literal> annotated method of <literal>org.jboss.tutorial.interceptor.bean.TracingInterceptor</literal> should wrap all calls
+				to <literal>EmailSystemBean</literal>'s business methods. The <literal>@Interceptors</literal> annotation can take an
+				array of classes, so you can bind more than one class-level interceptor this way, e.g.
+				<programlisting>
+					<![CDATA[
+ at Stateless
+ at Interceptors ({TracingInterceptor.class, SomeInterceptor.class})
+public class EmailSystemBean
+{
+   ...
+}
+					
+					]]>
+				</programlisting>
+				
+			</para>
+			
+			<sect5>
+				Class-level using xml :
+			</sect5>			
+			<para>
+				In the <literal>META-INF/ejb-jar.xml</literal> we have the following:
+				
+				<programlisting>
+					<![CDATA[
+<assembly-descriptor>
+   ...
+	  <!-- Class interceptor that will apply to all methods for EmailSystemBean -->
+	   <interceptor-binding>
+         <ejb-name>EmailSystemBean</ejb-name>
+         <interceptor-class>org.jboss.tutorial.interceptor.bean.OtherInterceptor</interceptor-class>
+      </interceptor-binding>
+   ...
+</assembly-descriptor>
+					
+					]]>
+				</programlisting>
+				
+				Note that here we are specifying the ejb-name of the bean we want to apply the interceptor to.
+				Hence, the <literal>@AroundInvoke</literal> annotated method of <literal>org.jboss.tutorial.interceptor.bean.OtherInterceptor</literal>
+				will wrap all calls to <literal>EmailSystemBean</literal>'s business methods.
+			</para>
+			
+	</para>
+	
+	<sect5>
+		Method-level interceptors :
+	</sect5>
+	
+	<para>
+		Just as we can define default and class-level interceptors, we can also bind an interceptor to a particular business method
+		of a bean
+		<sect5>
+			Method-level using annotations :
+		</sect5>
+		<para>
+			<literal>org.jboss.tutorial.interceptor.bean.EmailSystemBean</literal>'s <literal>sendBookingConfirmationMessage()</literal>
+			method has been annotated with the @Interceptors annotation specifying interceptors that will intercept when this perticular
+			method is invoked.
+			<programlisting>
+				<![CDATA[
+ at Interceptors({AccountsConfirmInterceptor.class})
+public void sendBookingConfirmationMessage(long orderId)
+{
+   ...
+}
+				
+				]]>
+			</programlisting>
+			
+			Method-level interceptors are in addition to default and class-level interceptors, meaning that when we call
+			<literal>EmailSystemBean.sendBookingConfirmationMessage()</literal> we get intercepted by
+			
+			<itemizedlist mark="opencircle">
+				<listitem>
+					<para>
+						DefaultInterceptor (default)
+					</para>
+				</listitem>
+				<listitem>
+					<para>
+						TracingInterceptor (class-level)
+					</para>
+				</listitem>
+				<listitem>
+					<para>
+						OtherInterceptor (class-level)
+					</para>
+				</listitem>
+				<listitem>
+					<para>
+						AccountsConfirmInterceptor (method-level)
+					</para>
+				</listitem>								
+			</itemizedlist>
+			
+			An interceptor method can choose to abort an invocation, by not calling 
+			<literal>InvocationContext.proceed()</literal>  as is done in <literal>AccountConfirmInterceptor</literal>'s interceptor method
+			when a confirmation already exists.						
+		</para>
+		
+		<sect5>
+			Method-level using xml :
+		</sect5>
+		<para>
+			We can also bind interceptors to a single business method within a bean using xml.
+			But first let's define an interceptor using xml. All the examples we have looked at so far have used the <literal>@AroundInvoke</literal>
+			annotation to mark the interceptor methods.	In <literal>META-INF/ejb-jar.xml</literal> we have the following:
+			<programlisting>
+				<![CDATA[
+<interceptors>
+     <interceptor>
+        <interceptor-class>org.jboss.tutorial.interceptor.bean.AccountsCancelInterceptor</interceptor-class>
+        <around-invoke>
+           <method-name>sendCancelMessage</method-name>
+        </around-invoke>
+		...
+		
+     </interceptor>   
+</interceptors>
+				
+				]]>
+			</programlisting>
+			This tells us that the <literal>sendCancelMessage()</literal> method of <literal>org.jboss.tutorial.interceptor.bean.AccountsCancelInterceptor</literal> 
+			is the interceptor method of this interceptor class. To bind interceptors to a particular method using xml, is much the same as how 
+			this was done for class-level interceptors apart from that we specify the <literal>method-name</literal> of the method we want to intercept.
+			From our <literal>META-INF/ejb-jar.xml</literal>:
+			<programlisting>
+				<![CDATA[
+ <assembly-descriptor>
+    ...
+	   <!-- Method interceptor will apply to sendBookingCancellationMessage for EmailSystemBean -->
+	   <interceptor-binding>
+         <ejb-name>EmailSystemBean</ejb-name>
+         <interceptor-class>org.jboss.tutorial.interceptor.bean.AccountsCancelInterceptor</interceptor-class>
+         <method>
+           <method-name>sendBookingCancellationMessage</method-name>
+         </method>
+      </interceptor-binding>
+
+    ...
+ </assembly-descriptor>
+				
+				]]>
+			</programlisting>
+			In the case of overloaded methods, we can further narrow down the method by specifying the method parameters, as in this example:
+			<programlisting>
+				<![CDATA[
+<assembly-descriptor>
+   	...
+	<!-- Method interceptor will apply to sendBookingCancellationMessage for EmailSystemBean -->
+	   <interceptor-binding>
+         <ejb-name>SomeBean</ejb-name>
+         <interceptor-class>SomeInterceptor</interceptor-class>
+         <method>
+           <method-name>methodWithParam</method-name>
+           <method-params>
+           		<method-param>int</method-param>
+           		<method-param>java.lang.String[]</method-param>
+           </method-params>
+         </method>
+      </interceptor-binding>
+</assembly-descriptor>
+				
+				]]>
+			</programlisting>
+			<literal>SomeInterceptor</literal> will only get applied to the method of <literal>SomeBean</literal> that matches the signature,
+			i.e. <literal>methodWithParam(int, java.lang.String[])</literal>
+		</para>
+		
+	</para>
+	
+	<sect5>
+		Exclusion of default and class interceptors :
+		
+		<para>
+			For some beans we may want to exclude the default interceptors configured for the deployment, and for some methods
+			within a bean class we may want to exclude the class interceptors for the bean (and/or the default interceptors)
+			
+			<sect5>
+				Annotations :
+				
+				<para>
+					The <literal>@javax.ejb.ExcludeDefaultInterceptors</literal> annotation can be applied to a bean class or a method.
+					If applied to a bean class, default interceptors will not get invoked for any of that bean class's methods. If applied
+					to a bean business method, default interceptors will not get invoked when calling that method.
+				</para>
+				
+				<para>
+					The <literal>@javax.ejb.ExcludeClassInterceptors</literal> annotation can be applied to a bean method. When this annotation
+					is used class-level interceptors will not get invoked when calling that method.
+					
+				</para>
+				
+				<para>
+					<literal>org.jboss.tutorial.interceptor.bean.EmailMDB</literal> defines
+					
+					<programlisting>
+						<![CDATA[
+ at ExcludeDefaultInterceptors        
+public class EmailMDB implements MessageListener
+{
+   ...
+}
+						
+						]]>
+					</programlisting>
+					so <literal>DefaultInterceptor</literal> is not invoked when invoking the <literal>EmailMDB.onMessage()</literal>	
+				</para>
+				
+				<para>
+					<literal>org.jboss.tutorial.interceptor.bean.EmailSystemBean</literal>'s  <literal>noop</literal> method is annotated with both
+					<literal>@ExcludeClassInterceptors</literal> and <literal>@ExcludeDefaultInterceptors</literal> and so will not get intercepted
+					by any of these.
+					
+					<programlisting>
+						<![CDATA[
+ at ExcludeClassInterceptors
+ at ExcludeDefaultInterceptors
+public void noop()
+{
+   System.out.println("<In EmailSystemBean.noop business method");
+   System.out.println("Exiting EmailSystemBean.noop business method>");
+}
+						
+						]]>
+					</programlisting>
+				</para>
+			</sect5>
+			
+			<sect5>
+				XML :
+				
+				<para>
+					We can also exclude class and method-level interceptors within an <literal>interceptor-binding</literal> by specifying the
+					<literal>exclude-class-interceptors</literal> and <literal>exclude-default-interceptors</literal> elements.
+					
+					<programlisting>
+						<![CDATA[
+<assembly-descriptor>
+      ...
+						
+	   <interceptor-binding>
+         <ejb-name>EmailSystemBean</ejb-name>
+         <exclude-default-interceptors>true</exclude-default-interceptors>
+         <exclude-class-interceptors>true</exclude-class-interceptors>
+         <method>
+           <method-name>noop2</method-name>
+         </method>
+      </interceptor-binding>
+	...
+</assembly-descriptor>
+						]]>
+					</programlisting>
+				</para>
+			</sect5>	
+			
+		</para>
+	</sect5>
+	
+	<sect5>
+		Inheritance Ordering :
+		
+		<para>
+			If an interceptor (or bean class) inherits from another class which has a method declared to be an interceptor method,
+			the interceptor methods from the super class will be invoked first. However, if the interceptor method in the superclass
+			has been overridden (regardless of if the overriding method is declared to be an interceptor method or not) the superclass
+			method is not invoked.
+		</para>
+		
+		<para>
+			Both <literal>org.jboss.tutorial.interceptor.bean.AccountsConfirmInterceptor</literal> and 
+			<literal>org.jboss.tutorial.interceptor.bean.AccountsCancelInterceptor</literal> inherit from 
+			<literal>org.jboss.tutorial.interceptor.bean.AccountsInterceptor</literal>.
+		</para>
+		
+		<para>
+			AccountsInterceptor declares the following interceptor method:
+			
+			<programlisting>
+				<![CDATA[
+ at AroundInvoke
+public Object intercept(InvocationContext ctx) throws Exception
+{
+   System.out.println("*** AccountsInterceptor intercepting " + ctx.getMethod().getName());
+   try
+   {
+      return ctx.proceed();
+   }
+   finally
+   {
+      System.out.println("*** AccountsInterceptor exiting");
+   }
+}
+				
+				]]>
+			</programlisting>
+			This method is overridden by <literal>AccountsConfirmInterceptor</literal>, even though it is not <literal>AccountsConfirmInterceptor</literal>'s 
+			interceptor method:
+			
+			<programlisting>
+				<![CDATA[
+public class AccountsConfirmInterceptor extends AccountsInterceptor
+{
+   ...
+   public Object intercept(InvocationContext ctx) throws Exception
+   {
+      //overrides AccountsInterceptor.intercept() so that will not be invoked
+      return null;
+   }
+
+   
+   @AroundInvoke
+   public Object sendConfirmMessage(InvocationContext ctx) throws Exception
+   {
+      ...
+   }
+}   
+				]]>
+			</programlisting>
+			So when invoking <literal>AccountsConfirmInterceptor</literal>, we simply invoke its <literal>sendConfirmMessage()</literal> method.
+			<literal>AccountsCancelInterceptor</literal>, on the other hand, does not override <literal>AccountsInterceptor.intercept()</literal>,
+			so when invoking <literal>AccountsCancelInterceptor</literal>, we first get intercepted by <literal>AccountsInterceptor.intercept()</literal>
+			followed by <literal>AccountsCancelInterceptor.sendCancelMessage()</literal>.
+					
+		</para>
+		
+	</sect5>
+	
+	<sect5>
+		Injection in interceptors:
+		<sect5>
+			Using Annotations :
+			<para>
+				Just like a bean class, an interceptor can be the target of dependency injection (see the "injection" tutorial for
+				details about injection). The format for how this works is the same, and the injection works off the same ENC as 
+				the bean to which the interceptor is bound.
+			</para>
+			<para>
+				<literal>org.jboss.tutorial.interceptor.bean.AccountsConfirmInterceptor</literal> has dependency injection set up using annotations:	
+				<programlisting>
+					<![CDATA[
+public class AccountsConfirmInterceptor extends AccountsInterceptor
+{
+   @Resource(mappedName="java:ConnectionFactory")
+   QueueConnectionFactory cf;
+   
+   @Resource(mappedName="queue/tutorial/accounts")
+   Queue queue;
+   
+   @PersistenceContext
+   EntityManager em;
+   
+   ...
+					
+					]]>
+				</programlisting>
+			</para>
+			Remember that interceptors follow the same lifecycle as the bean they are bound to. The interceptors are created at the same
+			time as the bean instance is created, and dependecy injection occurs before the first business method is called. In the example
+			just shown, the container:
+			<itemizedlist mark="opencircle">
+				<listitem>
+					<para>
+						Looks up <literal>java:ConnectionFactory</literal>, binds it in the ENC and injects this into the field <literal>cf</literal>
+					</para>
+				</listitem>
+				<listitem>
+					<para>
+						Looks up <literal>queue/tutorial/accounts</literal>, binds it in the ENC and injects this into the field <literal>queue</literal>
+					</para>
+				</listitem>
+				<listitem>
+					<para>
+						Obtains the default EntityManager and injects this into the field <literal>em</literal>
+					</para>
+				</listitem>
+				
+			</itemizedlist>
+			
+		</sect5>
+		
+		<sect5>
+			Using XML :
+			<para>
+				Injection, into interceptors, can also be configured via xml, using the traditional <literal>ejb-ref</literal>, <literal>ejb-local-ref</literal>,
+				<literal>resource-ref</literal>, <literal>resource-env-ref</literal> etc. which bind the global names. The only difference
+				from beans is that we put this into the {{interceptors}} element defining the interceptor.
+				<programlisting>
+					<![CDATA[
+<interceptors>
+     <interceptor>
+        <interceptor-class>org.jboss.tutorial.interceptor.bean.AccountsCancelInterceptor</interceptor-class>
+        <around-invoke>
+           <method-name>sendCancelMessage</method-name>
+        </around-invoke>
+        <resource-ref>
+        	<res-ref-name>jms/ConnFactory</res-ref-name>
+           <res-type>javax.jms.QueueConnectionFactory</res-type>
+           <res-auth>Container</res-auth>
+           <mapped-name>java:/ConnectionFactory</mapped-name>
+           <injection-target>
+              <injection-target-class>org.jboss.tutorial.interceptor.bean.AccountsCancelInterceptor</injection-target-class>
+              <injection-target-name>cf</injection-target-name>
+           </injection-target>
+        </resource-ref>
+        <resource-env-ref>
+        	<resource-env-ref-name>accountsQueue</resource-env-ref-name>
+           <resource-env-ref-type>javax.jms.Queue</resource-env-ref-type>
+           <mapped-name>queue/tutorial/accounts</mapped-name>
+           <injection-target>
+              <injection-target-class>org.jboss.tutorial.interceptor.bean.AccountsCancelInterceptor</injection-target-class>
+              <injection-target-name>queue</injection-target-name>
+           </injection-target>
+        </resource-env-ref>
+     </interceptor>   
+</interceptors>
+					
+					]]>
+				</programlisting>
+				<itemizedlist mark="opencircle">
+					<listitem>
+						<para>
+							The container looks up <literal>java:/ConnectionFactory</literal> in JNDI and creates the <literal>java:comp/env/jms/ConnFactory</literal>
+							entry in the bean's ENC, and following bean creation it injects the connection factory into <literal>AccountsCancelInterceptor</literal>'s 
+							<literal>cf</literal> field.
+						</para>
+					</listitem>
+					<listitem>
+						<para>
+							The container looks up <literal>queue/tutorial/accounts</literal> in JNDI and creates the <literal>java:comp/env/accountsQueue</literal> 
+							entry in the bean's ENC, and following bean creation it injects the queue into <literal>AccountsCancelInterceptor</literal>'s
+							<literal>queue</literal> field.						</para>
+					</listitem>					
+				</itemizedlist>
+			</para>
+		</sect5>
+	</sect5>
+	
+	<sect5>
+		Interceptor Ordering :
+		<para>
+			By default the ordering of interceptors when invoking a method are
+			<itemizedlist mark="number">
+				<listitem>
+					<para>
+						External interceptors
+					</para>
+				</listitem>
+				<listitem>
+					<para>
+						Default interceptors, if present
+					</para>
+				</listitem>				
+				<listitem>
+					<para>
+						Class interceptors, if present
+					</para>
+				</listitem>
+				<listitem>
+					<para>
+						Method interceptors, if present
+					</para>
+				</listitem>
+				<listitem>
+					<para>
+						Interceptor method on the bean class (using @AroundInvoke)
+					</para>
+				</listitem>	
+
+			</itemizedlist>
+			Within each group (default, class, method) the order of the interceptors are from left to right as defined in the @Interceptors annotation,
+			and then the xml interceptors.			
+		</para>
+	
+		<sect5>
+			Overriding interceptor ordering :
+			
+			<para>
+				You can override the default sort order of the external interceptors by specifiying an <literal>interceptor-binding</literal> with an <literal>interceptor-order</literal>
+				specifying the order of the interceptors
+				<programlisting>
+					<![CDATA[
+<assembly-descriptor>					
+      <interceptor-binding>
+         <ejb-name>EmailSystemBean</ejb-name>
+         <interceptor-order>
+            <interceptor-class>org.jboss.tutorial.interceptor.bean.AccountsCancelInterceptor</interceptor-class>
+            <interceptor-class>org.jboss.tutorial.interceptor.bean.DefaultInterceptor</interceptor-class>
+            <interceptor-class>org.jboss.tutorial.interceptor.bean.OtherInterceptor</interceptor-class>
+            <interceptor-class>org.jboss.tutorial.interceptor.bean.TracingInterceptor</interceptor-class>
+         </interceptor-order>
+         <method>
+           <method-name>sendBookingCancellationMessage</method-name>
+         </method>
+      </interceptor-binding>
+      ...
+</assembly-descriptor>
+					
+					]]>
+				</programlisting>
+			</para>
+			So when invoking <literal>EmailSystemBean.sendBookingCancellationMessage</literal> we will get the following interception order,
+			quite different from the default sort order
+			<itemizedlist mark="number">
+				<listitem>
+					<para>
+						AccountsCancelInterceptor (method-level)
+					</para>
+				</listitem>
+				<listitem>
+					<para>
+						DefaultInterceptor (default interceptor)
+					</para>
+				</listitem>
+				<listitem>
+					<para>
+						OtherInterceptor (2nd class-level interceptor)
+					</para>
+				</listitem>
+				<listitem>
+					<para>
+						TracingInterceptor (1st class-level interceptor)
+					</para>
+				</listitem>				
+			
+			</itemizedlist>
+			
+		</sect5>
+		
+	</sect5>
+	
+	<sect5>
+		InvocationContext :
+		<para>
+			As you have seen the <literal>@AroundInvoke</literal> annotated interceptor methods all take a parameter of type 
+			<literal>javax.ejb.InvocationContext</literal>. The definition of InvocationContext is:
+			
+			<programlisting>
+				<![CDATA[
+
+package javax.interceptor;
+				
+public interface InvocationContext {
+				
+	public java.lang.Object getTarget();
+  
+    public java.lang.reflect.Method getMethod();
+	
+	public java.lang.Object[] getParameters();
+  	
+  	public void setParameters(java.lang.Object[] arg0);
+  
+	public java.util.Map getContextData();
+  
+	public java.lang.Object proceed() throws java.lang.Exception;
+}					
+				]]>
+			
+			</programlisting>
+			
+			<para>
+				<literal>getBean()</literal> - returns the bean instance on which we are calling a method
+			</para>
+			<para>
+				<literal>getMethod()</literal> - returns the method we are calling on the bean instance
+			</para>
+			<para>
+				<literal>getParameters()</literal> - returns the parameters for the method call
+			</para>
+			<para>
+				<literal>setParameters()</literal> - allows you to modify the parameters for the method call
+			</para>
+			<para>
+				<literal>getContextData</literal> - The EJB interceptions are stateless, but the same InvocationContext instance
+				is used for each interceptor method in a chain. If you want to pass values between interceptor methods in the 
+				business method invocation you can store them in the Map retured by getContextData().
+			</para>
+			<para>
+				<literal>proceed</literal> - As discussed, invokes the next interceptor, or if we are in the last interceptor
+				invokes the target bean method.
+			</para>
+			
+			In some case we might want access to the EJBContext, this can be injected into the interceptor instance using the 
+			<literal>@Resource</literal> annotation. The AroundInvoke methods share the JNDI name space of the bean for whose
+			methods they are invoked and execute within the same transaction and security context as the business methods for
+			which they are invoked.
+			
+		</para>
+	</sect5>
+	
+	<sect5>
+	
+Building and Running
+	<para>
+			<note>
+					<para>
+						To build and run the example, make sure you have installed JBoss 5.x. 
+						See the <xref linkend="JBossAS5">installation section</xref> for details.
+					</para>
+			</note>
+		
+			<sect5>
+		Ant Users:
+			</sect5>
+				<para>
+				Make sure your JBossAS-5.x is running
+				</para>
+			<programlisting>
+			<![CDATA[
+$ ant
+$ ant run
+
+run:
+     [java] Starting
+     [java] 
+     [java] Calling emailLostPassword
+     [java] Waiting 2 seconds
+     [java] 
+     [java] Calling sendBookingConfirmationMessage
+     [java] Waiting 2 seconds
+     [java] 
+     [java] Calling sendBookingConfirmationMessage
+     [java] Waiting 2 seconds
+     [java] 
+     [java] Calling sendBookingCancellationMessage
+     [java] Waiting 2 seconds
+     [java] 
+     [java] Calling noop
+     [java] Waiting 2 seconds
+     [java] 
+     [java] Calling noop2
+     [java] Waiting 2 seconds
+     [java] Done
+		     
+		     ]]>
+			</programlisting>
+		
+			<sect5>
+		Maven Users: <xref linkend="Maven_Users_TODO">TODO</xref>
+			</sect5>
+			
+			<programlisting>
+$ mvn clean install
+			</programlisting>	
+
+			<para>
+				<programlisting>
+					<![CDATA[
+21:49:01,888 INFO  [STDOUT] *** DefaultInterceptor intercepting emailLostPassword
+21:49:01,889 INFO  [STDOUT] *** TracingInterceptor intercepting emailLostPassword
+21:49:01,889 INFO  [STDOUT] *** OtherInterceptor intercepting emailLostPassword
+21:49:01,889 INFO  [STDOUT] *** EmailSystemBean.myBeanInterceptor - username: whatever
+21:49:01,889 INFO  [STDOUT] <In EmailSystemBean.emailLostPassword business method
+21:49:02,083 INFO  [STDOUT] Message sent successfully to remote queue.
+21:49:02,130 INFO  [STDOUT] Exiting EmailSystemBean.emailLostPassword business method>
+21:49:02,130 INFO  [STDOUT] *** OtherInterceptor exiting
+21:49:02,130 INFO  [STDOUT] *** TracingInterceptor invocation of org.jboss.tutorial.interceptor.bean.EmailSystemBean.emailLostPassword() took 241ms
+21:49:02,130 INFO  [STDOUT] *** DefaultInterceptor exiting
+21:49:02,179 WARN  [InterceptorsFactory] EJBTHREE-1246: Do not use InterceptorsFactory with a ManagedObjectAdvisor, InterceptorRegistry should be used via the bean container
+21:49:02,180 WARN  [InterceptorsFactory] EJBTHREE-1246: Do not use InterceptorsFactory with a ManagedObjectAdvisor, InterceptorRegistry should be used via the bean container
+21:49:02,180 WARN  [InterceptorRegistry] applicable interceptors is non-existent for public void org.jboss.tutorial.interceptor.bean.EmailMDB.onMessage(javax.jms.Message)
+21:49:02,181 WARN  [InterceptorRegistry] applicable interceptors is non-existent for public java.lang.Object org.jboss.tutorial.interceptor.bean.EmailMDB.mdbInterceptor(javax.interceptor.InvocationContext) throws java.lang.Exception
+21:49:02,182 WARN  [InterceptorRegistry] applicable interceptors is non-existent for public void org.jboss.tutorial.interceptor.bean.EmailMDB.onMessage(javax.jms.Message)
+21:49:02,184 WARN  [InterceptorRegistry] applicable interceptors is non-existent for public java.lang.Object org.jboss.tutorial.interceptor.bean.EmailMDB.mdbInterceptor(javax.interceptor.InvocationContext) throws java.lang.Exception
+21:49:02,185 INFO  [STDOUT] *** EmailMDB.mdbInterceptor intercepting
+21:49:02,185 INFO  [STDOUT] 
+----------------
+EMailMDB - Got message, sending email
+----------------
+21:49:04,251 INFO  [STDOUT] *** DefaultInterceptor intercepting sendBookingConfirmationMessage
+21:49:04,251 INFO  [STDOUT] *** TracingInterceptor intercepting sendBookingConfirmationMessage
+21:49:04,251 INFO  [STDOUT] *** OtherInterceptor intercepting sendBookingConfirmationMessage
+21:49:04,251 INFO  [STDOUT] *** AccountsConfirmInterceptor intercepting
+21:49:04,395 INFO  [STDOUT] *** AccountsConfirmInterceptor - recording confirmation
+21:49:04,431 INFO  [STDOUT] *** AccountsConfirmInterceptor - notifying accounts dept sendBookingConfirmationMessage
+21:49:04,440 INFO  [STDOUT] <In EmailSystemBean.sendBookingConfirmationMessage business method
+21:49:04,455 WARN  [InterceptorsFactory] EJBTHREE-1246: Do not use InterceptorsFactory with a ManagedObjectAdvisor, InterceptorRegistry should be used via the bean container
+21:49:04,455 WARN  [InterceptorsFactory] EJBTHREE-1246: Do not use InterceptorsFactory with a ManagedObjectAdvisor, InterceptorRegistry should be used via the bean container
+21:49:04,455 WARN  [InterceptorRegistry] applicable interceptors is non-existent for public void org.jboss.tutorial.interceptor.bean.AccountsMDB.onMessage(javax.jms.Message)
+21:49:04,457 WARN  [InterceptorRegistry] applicable interceptors is non-existent for public void org.jboss.tutorial.interceptor.bean.AccountsMDB.onMessage(javax.jms.Message)
+21:49:04,458 INFO  [STDOUT] *** DefaultInterceptor intercepting onMessage
+21:49:04,459 INFO  [STDOUT] 
+----------------
+AccountsMDB - Got message Confirming order 100
+----------------
+21:49:04,459 INFO  [STDOUT] *** DefaultInterceptor exiting
+21:49:04,466 INFO  [STDOUT] Message sent successfully to remote queue.
+21:49:04,467 INFO  [STDOUT] Exiting EmailSystemBean.sendBookingConfirmationMessage business method>
+21:49:04,467 INFO  [STDOUT] *** AccountsConfirmInterceptor exiting
+21:49:04,467 INFO  [STDOUT] *** OtherInterceptor exiting
+21:49:04,467 INFO  [STDOUT] *** TracingInterceptor invocation of org.jboss.tutorial.interceptor.bean.EmailSystemBean.sendBookingConfirmationMessage() took 216ms
+21:49:04,467 INFO  [STDOUT] *** DefaultInterceptor exiting
+21:49:04,478 INFO  [STDOUT] *** EmailMDB.mdbInterceptor intercepting
+21:49:04,478 INFO  [STDOUT] 
+----------------
+EMailMDB - Got message, sending email
+----------------
+21:49:06,533 INFO  [STDOUT] *** DefaultInterceptor intercepting sendBookingConfirmationMessage
+21:49:06,533 INFO  [STDOUT] *** TracingInterceptor intercepting sendBookingConfirmationMessage
+21:49:06,533 INFO  [STDOUT] *** OtherInterceptor intercepting sendBookingConfirmationMessage
+21:49:06,533 INFO  [STDOUT] *** AccountsConfirmInterceptor intercepting
+21:49:06,547 INFO  [STDOUT] *** AccountsConfirmInterceptor - order has already been confirmed aborting
+21:49:06,548 INFO  [STDOUT] *** AccountsConfirmInterceptor exiting
+21:49:06,548 INFO  [STDOUT] *** OtherInterceptor exiting
+21:49:06,548 INFO  [STDOUT] *** TracingInterceptor invocation of org.jboss.tutorial.interceptor.bean.EmailSystemBean.sendBookingConfirmationMessage() took 15ms
+21:49:06,548 INFO  [STDOUT] *** DefaultInterceptor exiting
+21:49:08,577 INFO  [STDOUT] *** AccountsInterceptor intercepting sendBookingCancellationMessage
+21:49:08,577 INFO  [STDOUT] *** AccountsCancelInterceptor intercepting sendBookingCancellationMessage
+21:49:08,577 INFO  [STDOUT] *** AccountsConfirmInterceptor - notifying accounts dept
+21:49:08,593 INFO  [STDOUT] *** DefaultInterceptor intercepting sendBookingCancellationMessage
+21:49:08,593 INFO  [STDOUT] *** OtherInterceptor intercepting sendBookingCancellationMessage
+21:49:08,593 INFO  [STDOUT] *** TracingInterceptor intercepting sendBookingCancellationMessage
+21:49:08,593 INFO  [STDOUT] <In EmailSystemBean.sendBookingCancellationMessage business method
+21:49:08,605 INFO  [STDOUT] Message sent successfully to remote queue.
+21:49:08,606 INFO  [STDOUT] Exiting EmailSystemBean.sendBookingCancellationMessage business method>
+21:49:08,606 INFO  [STDOUT] *** TracingInterceptor invocation of org.jboss.tutorial.interceptor.bean.EmailSystemBean.sendBookingCancellationMessage() took 13ms
+21:49:08,606 INFO  [STDOUT] *** OtherInterceptor exiting
+21:49:08,606 INFO  [STDOUT] *** DefaultInterceptor exiting
+21:49:08,606 INFO  [STDOUT] *** AccountsCancelInterceptor exiting
+21:49:08,606 INFO  [STDOUT] *** AccountsInterceptor exiting
+21:49:08,617 INFO  [STDOUT] *** EmailMDB.mdbInterceptor intercepting
+21:49:08,617 INFO  [STDOUT] 
+----------------
+EMailMDB - Got message, sending email
+----------------
+21:49:08,620 INFO  [STDOUT] *** DefaultInterceptor intercepting onMessage
+21:49:08,620 INFO  [STDOUT] 
+----------------
+AccountsMDB - Got message Cancelling order 100
+----------------
+21:49:08,620 INFO  [STDOUT] *** DefaultInterceptor exiting
+21:49:10,628 INFO  [STDOUT] <In EmailSystemBean.noop business method
+21:49:10,628 INFO  [STDOUT] Exiting EmailSystemBean.noop business method>
+21:49:12,648 INFO  [STDOUT] <In EmailSystemBean.noop2 business method
+21:49:12,648 INFO  [STDOUT] Exiting EmailSystemBean.noop2 business method>
+
+						]]>
+					</programlisting>
+			</para>
+			<note>
+				<para>
+					Look at the JBoss console window to see the output of the interceptions taking place, the EmailMDB and AccountsMDB
+					might occur in slightly different places since they execute asynchronously.
+				</para>
+				<para>
+					You can ignore the [WARN] messages:
+					<programlisting>
+21:49:02,179 WARN  [InterceptorsFactory] EJBTHREE-1246: Do not use InterceptorsFactory with a ManagedObjectAdvisor, InterceptorRegistry should be used via the bean container
+21:49:02,180 WARN  [InterceptorsFactory] EJBTHREE-1246: Do not use InterceptorsFactory with a ManagedObjectAdvisor, InterceptorRegistry should be used via the bean container
+21:49:02,180 WARN  [InterceptorRegistry] applicable interceptors is non-existent for public void org.jboss.tutorial.interceptor.bean.EmailMDB.onMessage(javax.jms.Message)
+21:49:02,181 WARN  [InterceptorRegistry] applicable interceptors is non-existent for public java.lang.Object org.jboss.tutorial.interceptor.bean.EmailMDB.mdbInterceptor(javax.interceptor.InvocationContext) throws java.lang.Exception
+21:49:02,182 WARN  [InterceptorRegistry] applicable interceptors is non-existent for public void org.jboss.tutorial.interceptor.bean.EmailMDB.onMessage(javax.jms.Message)
+21:49:02,184 WARN  [InterceptorRegistry] applicable interceptors is non-existent for public java.lang.Object org.jboss.tutorial.interceptor.bean.EmailMDB.mdbInterceptor(javax.interceptor.InvocationContext) throws java.lang.Exception
+						
+					</programlisting>
+				</para>				
+			</note>
+		</para>	
+	</sect5>
+</chapter>

Added: projects/ejb3/trunk/docs/tutorial/guide/en/modules/jndibinding.xml
===================================================================
--- projects/ejb3/trunk/docs/tutorial/guide/en/modules/jndibinding.xml	                        (rev 0)
+++ projects/ejb3/trunk/docs/tutorial/guide/en/modules/jndibinding.xml	2009-01-05 07:49:00 UTC (rev 82605)
@@ -0,0 +1,128 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<chapter id="JNDI Bindings">
+	<title>Binding your beans in JNDI</title>
+	<para>
+		By default, when the application is deployed in a jar, session beans will bind to JNDI in the form <literal>ejbName/remote</literal> for remote 
+		interfaces and <literal>ejbName/local</literal> in the case of local interfaces. When the EJBs are deployed in an .ear file, the default
+		jndi binding will be prepended by the name of the .ear file.  So if the ear file name is <literal>foo.ear</literal> the default jndi 
+		names would be <literal>foo/EJB-NAME/remote</literal> and <literal>foo/EJB-NAME/local</literal>. You can override this behavior
+		by defining your own <literal>@org.jboss.ejb3.annotation.LocalBinding</literal> and/or <literal>@org.jboss.ejb3.annotation.RemoteBinding</literal>.
+		
+	</para>
+	
+	<sect5>
+		Local Interface JNDI Binding :
+		<para>
+			To change the JNDI name for your local interface use the <literal>@org.jboss.ejb3.annotation.LocalBinding</literal> annotation.
+			<programlisting>
+				<![CDATA[
+ at Stateless
+ at LocalBinding(jndiBinding="custom/MySession")
+public class MySessionBean implements MySession
+{
+}
+				
+				]]>				
+			</programlisting>
+		</para>
+		
+	</sect5>
+	
+	<sect5>
+		Remote Interface JNDI Binding :
+		<para>
+			To change the JNDI name for your remote interface use the <literal>@org.jboss.ejb3.annotation.RemoteBinding</literal> annotation.
+			
+			<programlisting>
+				<![CDATA[
+ at Stateless
+ at RemoteBinding(jndiBinding="custom/remote/MySession")
+public class MySessionBean implements MySession
+{
+}
+				
+				]]>
+			</programlisting>
+		</para>
+	</sect5>
+	
+	<sect5>
+		Persistence unit JNDI Bindings :
+		<para>
+			Persistence units are not bound into JNDI by default. You can bind them by defining some jboss specific properties
+			in persistence.xml.
+			<programlisting>
+				<![CDATA[
+<persistence>
+   <persistence-unit name="manager1">
+      <jta-data-source>java:/DefaultDS</jta-data-source>
+      <jar-file>MyApp.jar</jar-file>
+      <class>org.acme.Employee</class>
+      <class>org.acme.Person</class>
+      <class>org.acme.Address</class>
+      <properties>
+         <property name="jboss.entity.manager.jndi.name" value="java:/Manager1"/>
+         <property name="jboss.entity.manager.factory.jndi.name" value="java:/Manager1Factory"/>
+      </properties>
+   </persistence-unit>
+</persistence>
+				
+				]]>
+			</programlisting>
+			<note>
+				
+				<xref linkend="JNDIBinding">Not supported in JBossAS-5.0 GA</xref> 
+				
+			</note>
+			
+		</para>
+	</sect5>
+	
+	<sect5>
+		Client :
+		<para>
+			Open up <literal>org.jboss.tutorial.jndibinding.client.Client</literal>.
+			You'll see that it looks up the stateless bean under "Calculator". Also notice that there is no Home interface
+			and you can begin executing on the stateless bean right away.
+		</para>
+	</sect5>
+	
+	<sect5>
+	
+Building and Running
+	<para>
+			<note>
+					<para>
+						To build and run the example, make sure you have installed JBoss 5.x. 
+						See the <xref linkend="JBossAS5">installation section</xref> for details.
+					</para>
+			</note>
+		
+			<sect5>
+		Ant Users:
+			</sect5>
+				<para>
+				Make sure your JBossAS-5.x is running
+				</para>
+			<programlisting>
+			<![CDATA[
+$ ant
+$ ant run
+
+run:
+     [java] 1 + 1 = 2
+     [java] 1 - 1 = 0
+		     
+		     ]]>
+			</programlisting>
+		
+			<sect5>
+		Maven Users: <xref linkend="Maven_Users_TODO">TODO</xref>
+			</sect5>
+			
+			<programlisting>
+$ mvn clean install
+			</programlisting>	
+		</para>
+	</sect5>	
+</chapter>

Added: projects/ejb3/trunk/docs/tutorial/guide/en/modules/mdb.xml
===================================================================
--- projects/ejb3/trunk/docs/tutorial/guide/en/modules/mdb.xml	                        (rev 0)
+++ projects/ejb3/trunk/docs/tutorial/guide/en/modules/mdb.xml	2009-01-05 07:49:00 UTC (rev 82605)
@@ -0,0 +1,22 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<chapter id="Message Driven Beans">
+	<title>Introduction to Message Driven Beans in EJB3</title>
+	<para>
+		This example shows you how to implement an MDB with EJB 3.0 using annotations.
+		
+	</para>
+	<para>
+		Take a look at <literal>org.jboss.tutorial.mdb.bean.ExampleMDB</literal>. The @MessageDriven annotation
+		defines the bean as an MDB. The <literal>activationConfig</literal> attribute contains much of the MDB configuration via 
+		<literal>@ActivationConfigProperty</literal>. Also notice that the MDB source contains properties for 
+		<literal>destinationType</literal> and <literal>destination</literal>
+		
+	</para>
+	
+	<para>
+		The following is the list of standard Activation Config Properties available from the JCA 1.5 specification.
+		Also listed are the respective types and default values where defined.
+		
+		
+	</para>
+</chapter>

Added: projects/ejb3/trunk/docs/tutorial/guide/en/modules/mdb_deployment_descriptor.xml
===================================================================
--- projects/ejb3/trunk/docs/tutorial/guide/en/modules/mdb_deployment_descriptor.xml	                        (rev 0)
+++ projects/ejb3/trunk/docs/tutorial/guide/en/modules/mdb_deployment_descriptor.xml	2009-01-05 07:49:00 UTC (rev 82605)
@@ -0,0 +1,89 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<chapter id="Message Driven Beans with deployment descriptor">
+	<title>Configuring Message Driven Beans through deployment descriptors</title>
+	<para>
+		You configure properties by using the &lt;message-driven&gt; element and sub elements which correspond to the 
+		<literal>@ActivationConfigProperty</literal> annotation. 
+		<para>ejb-jar.xml:</para> 
+		<programlisting>
+			<![CDATA[
+<message-driven>
+	<ejb-name>ExampleMDB</ejb-name>
+	<ejb-class>org.jboss.tutorial.mdb_deployment_descriptor.bean.ExampleMDB</ejb-class>
+     <transaction-type>Bean</transaction-type>
+     <message-destination-type>javax.jms.Queue</message-destination-type>
+   <activation-config>   
+      <activation-config-property>
+      	<activation-config-property-name>acknowledgeMode</activation-config-property-name>
+      	<activation-config-property-value>AUTO_ACKNOWLEDGE</activation-config-property-value>
+      </activation-config-property>
+    </activation-config>
+    
+</message-driven>
+			
+			]]>
+		</programlisting>
+		
+		<para>jboss.xml</para>
+		<programlisting>
+			<![CDATA[
+<message-driven>
+   <ejb-name>ExampleMDB</ejb-name>
+   <destination-jndi-name>queue/tutorial/example</destination-jndi-name>
+</message-driven>
+			]]>
+		</programlisting>
+		
+		The <literal>queue/tutorial/example</literal> is configured through the <literal>queue-example-service.xml</literal>
+	</para>
+	
+	<sect5>
+	
+Building and Running
+	<para>
+			<note>
+					<para>
+						To build and run the example, make sure you have installed JBoss 5.x. 
+						See the <xref linkend="JBossAS5">installation section</xref> for details.
+					</para>
+			</note>
+		
+			<sect5>
+		Ant Users:
+			</sect5>
+				<para>
+				Make sure your JBossAS-5.x is running
+				</para>
+			<programlisting>
+			<![CDATA[
+$ ant
+$ ant run
+
+run:
+     [java] Message sent successfully to remote queue.
+
+		     
+		     ]]>
+			</programlisting>
+		
+			<sect5>
+		Maven Users: <xref linkend="Maven_Users_TODO">TODO</xref>
+			</sect5>
+			
+			<programlisting>
+$ mvn clean install
+			</programlisting>
+			
+			On the server console, you will notice the following logs:
+			<programlisting>
+				<![CDATA[
+23:37:38,175 INFO  [STDOUT] ----------------
+23:37:38,175 INFO  [STDOUT] Received message
+23:37:38,175 INFO  [STDOUT] ----------------
+				
+				]]>
+			</programlisting>				
+		</para>
+	</sect5>	
+	
+</chapter>
\ No newline at end of file

Modified: projects/ejb3/trunk/docs/tutorial/guide/en/modules/todo.xml
===================================================================
--- projects/ejb3/trunk/docs/tutorial/guide/en/modules/todo.xml	2009-01-05 04:12:59 UTC (rev 82604)
+++ projects/ejb3/trunk/docs/tutorial/guide/en/modules/todo.xml	2009-01-05 07:49:00 UTC (rev 82605)
@@ -12,4 +12,35 @@
 
 		</section>
 		
+		<section id="JNDIBinding">
+			<title>TODO - Support for binding the EntityManager and EntityManagerFactory in JNDI</title>
+			<para>
+				JBoss-5.0 GA does NOT support binding the EntityManager and EntityManagerFactory in JNDI, using
+				the following properties in persistence.xml:
+				
+				<programlisting>
+					<![CDATA[
+<persistence>
+   <persistence-unit name="manager1">
+		...
+      <properties>
+         <property name="jboss.entity.manager.jndi.name" value="java:/Manager1"/>
+         <property name="jboss.entity.manager.factory.jndi.name" value="java:/Manager1Factory"/>
+      </properties>
+   </persistence-unit>
+</persistence>
+				
+					]]>
+				</programlisting>
+				We are tracking this in our EJBTHREE JIRA.		 
+			</para>
+
+		</section>
+		
+		<section id="InvocationContext_Javadoc">
+			<title>Point to the javadocs of InvocationContext in the "interceptor" tutorial guide</title>
+			<para>
+				Better point to javadocs instead of the listing the methods in the guide
+			</para>
+		</section>			
 </chapter>
\ No newline at end of file




More information about the jboss-cvs-commits mailing list