<document>
<header>
<product>resin-ee</product>
<type>tutorial</type>
<tutorial-startpage>stateless</tutorial-startpage>
<title>Local Stateless Session Hello</title>
<description>

<p>Stateless sessions make database queries and updates robust by
setting transaction boundaries at each business method.
This <var/stateless session/> bean example annotates a single
business method with a SUPPORTS transaction attribute, marking the
method as a read-only transaction boundary.</p>

<p>See also:</p>
<ul>
  <li>The <a href="../resin-xa/index.xtp">Resin Transaction</a> example for a more detailed description of method transaction enhancement.
  <li>The <a href="../cmp-xa/index.xtp">CMP Transaction</a> example for a traditional session bean pattern.
  <li>The <a href="ejb3|bean-ann.xtp#@TransactionAttribute">@TransactionAttribute</a> reference.
</ul>

</description>
</header>

<body>
<summary/>

<p>A Hello, World example for EJB 3.0 is much simpler than for earlier
versions of EJB.  To implement the EJB you need to implement:</p>

<ul>
<li>A local interface
<li>The bean implementation
</ul>

<p>To configure Resin to be a server for the EJB you need to:</p>

<ul>
<li>Configure the ejb-server
<li>Configure the client
</ul>

<p>In this tutorial, a simple "Hello" EJB is created and
deployed within Resin.</p>

<section title="Files in this tutorial">
<deftable>
<tr><td><viewfile-link file="WEB-INF/web.xml"/>
    <td>web.xml configuration
<tr><td><viewfile-link file="WEB-INF/classes/example/Hello.java"/>
    <td>The local interface for the stateless session bean
<tr><td><viewfile-link file="WEB-INF/classes/example/HelloBean.java"/>
    <td>The implementation for the stateless session bean
<tr><td><viewfile-link file="WEB-INF/classes/example/HelloServlet.java"/>
    <td>The client for the stateless session bean
</deftable>
</section>

<section title="Local Interface">

<p>The remote interface defines the client view of the bean.
It declares all the business methods.  Our
only business method is the <code/hello/> method.</p>

<example title="Hello.java" file="WEB-INF/classes/example/Hello.java">
package example;

public interface Hello {
  public String hello();
}
</example>

</section>

<section title="Bean Implementation">

<p>The second class for EJBs is the bean implementation class.  It implements
the functionality provided by the remote interface.</p> 

<example title="HelloBean.java" file="WEB-INF/classes/example/HelloBean.java">
package example;

import static javax.ejb.TransactionAttributeType.SUPPORTS;

@javax.ejb.Stateless
public class HelloBean implements Hello {
  private String _greeting = "Default Hello";

  <a href="ejb3|inject.xtp#@Inject">@javax.ejb.Inject</a>
  public void setGreeting(String greeting)
  {
    _greeting = greeting;
  }

  @javax.ejb.TransactionAttribute(SUPPORTS)
  public String hello()
  {
    return _greeting;
  }
}
</example>

<section title="@Stateless">

<p>The @Stateless annotation marks the bean as a stateless session
bean.  Resin will create a stub implementing <code>Hello</code> and
store it in JNDI at "java:comp/env/ejb/HelloBean".</p>

<p>The @Stateless annotation can have an optional <code>name</code>
value which overrides the default name of "HelloBean".</p>

</section>

<section title="@Inject">

<p>The <a href="ejb3|inject.xtp#@Inject">@javax.ejb.Inject</a>
annotation tells Resin to lookup the greeting from JNDI when the
session bean is created.  The JNDI name will be
java:comp/env/greeting.</p>

<p>In this example, the greeting is configured with an &lt;env-entry>
in the web.xml.</p>

</section>

<section title="Alternate Dependency Injection">

<p>The EJB 3.0 draft spec's dependency injection is somewhat
inflexible since the greeting is required to be in JNDI.  Resin
offers a more flexible dependency injection configuration based
on the configuration file.  By setting the value in the configuration
file, Resin's alternate dependency injection adds more flexibility and
some clarity.</p>

<example>
&lt;ejb-server jndi-name="java:comp/env/ejb">
  &lt;bean type="qa.TestBean">
    &lt;init greeting="Hello, World from web.xml"/>
  &lt;/bean>
&lt;/ejb-server>
</example>

</section>

<section title="@TransactionAttribute">

<p>Managing transactions is the primary purpose of stateless
session beans.  Transactions are a more powerful version of
a <code>synchronized</code> lock used to protect database integrity.
<a
href="ejb3|bean-ann.xtp#@TransactionAttribute">@TransactionAttribute</a>
marks the transaction boundary for each business method.</p>

<example>
@javax.ejb.TransactionAttribute(SUPPORTS)
public String hello()
</example>

<p>The <code>hello()</code> business method uses SUPPORTS because it's
a read-only method.  It doesn't need to start a new transaction on its
own, but will participate in any transaction that already exists.</p>

<p>The REQUIRED transaction value starts up a new transaction if none
already exists.  It's used when updating database values.</p>

<deftable>
<tr><th>TransactionAttribute<th>meaning
<tr><td>REQUIRED<td>Start a new transaction if necessary
<tr><td>SUPPORTS<td>Don't start a new transaction, but use one if it
exists
</deftable>

</section>

</section>

<section title="Configuring the Resin EJB server">

<p><code>&lt;ejb-server&gt;</code> configure the Resin EJB server.
Typically it configures the EJB root using jndi-name and configures
a number of EJB classes using &lt;bean>.  The &lt;bean> entry will
look at the bean's annotations to enhance the class.</p>

<example title="ejb-server in web.xml" file="WEB-INF/web.xml">
&lt;web-app xmlns="http://caucho.com/ns/resin"&gt;

  ...
  &lt;env-entry env-entry-name="greeting"
             env-entry-type="java.lang.String"
             env-entry-value="Hello, World."/>

  &lt;ejb-server jndi-name="java:comp/env/ejb">
    &lt;bean type="qa.TestBean"/>
  &lt;/ejb-server>
    
  ...

&lt;/web-app&gt;
</example>

<p>The &lt;bean> can optionally configure the bean instances with an
&lt;init> tag as described in the alternate dependency injection section.</p>

</section>

<section title="Client">

<example file="WEB-INF/classes/example/HelloServlet.java">
public class HelloServlet extends GenericServlet {
  private Hello _hello;

  @javax.ejb.EJB
  public void setHello(Hello hello)
  {
    _hello = hello;
  }

  public void service(HttpServletRequest req, HttpServletResponse res)
    throws IOException, ServletException
  {
    PrintWriter out = res.getWriter();
    
    out.println(_hello.hello());
  }
}
</example>

<section title="@EJB">

<p>The <a href="ejb3|cmp-inject.xtp#@EJB">@EJB</a> annotation tells
Resin to lookup the session bean in JNDI with name
"java:comp/env/ejb/HelloBean".</p>

<p>The servlet could also lookup the Hello bean with JNDI in the
<code>init()</code> method or use an &lt;init> configuration in the
web.xml:

<example title="alternative configuration">
&lt;servlet servlet-name="hello" servlet-class="example.HelloServlet">
  &lt;init hello="\${jndi:lookup('java:comp/env/ejb/HelloBean')}"/>
&lt;/servlet>
</example>

</section>

</section>

</body>
</document>
