Resin 4 Java EE Application Server EJB Tutorial
From Resin 4.0 Wiki
Contents |
EJB Tutorials
Local Stateless Session Hello
Stateless sessions make database queries and updates robust by setting transaction boundaries at each business method. This stateless session bean example annotates a single business method with a SUPPORTS transaction attribute, marking the method as a read-only transaction boundary.
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:
- A local interface
- The bean implementation
To configure Resin to be a server for the EJB you need to:
- Configure the ejb-stateless-bean
- Inject the bean into the application servlet
In this tutorial, a simple "Hello" EJB is created and deployed within Resin.
Files in this tutorial
File | Description |
---|---|
WEB-INF/web.xml |
web.xml configuration |
WEB-INF/classes/example/Hello.java |
The local interface for the stateless session bean |
WEB-INF/classes/example/HelloBean.java |
The implementation for the stateless session bean |
WEB-INF/classes/example/HelloServlet.java |
The client for the stateless session bean |
Local Interface
The remote interface defines the client view of the bean.
It declares all the business methods. Our
only business method is the hello
method.
Hello.java
package example; public interface Hello { public String hello(); }
Bean Implementation
The second class for EJBs is the bean implementation class. It implements the functionality provided by the remote interface.
HelloBean.java
package example; import javax.ejb.Stateless; import javax.ejb.TransactionAttribute; import static javax.ejb.TransactionAttributeType.SUPPORTS; import javax.inject.Named; @Stateless public class HelloBean implements Hello { @Inject @Named("greeting") private String _greeting; @TransactionAttribute(SUPPORTS) public String hello() { return _greeting; } }
@Stateless
The @Stateless annotation marks the bean as a stateless session
bean. Resin will create a stub implementing Hello
and
store it in the Java Injection directory with type Hello
and
name @Name("HelloBean")
.
The @Stateless annotation can have an optional name
value which overrides the default name of "HelloBean".
@Name
The @com.caucho.config.Name annotation tells Resin to lookup the
greeting String
in Java Injection directory using Resin's internal @Name binding "greeting" when the
session bean is created.
In this example, the greeting is configured with an <env-entry> in the web.xml.
Alternate Dependency Injection
In some cases, it may be clearer to configure the session bean directly, rather than using Java Injection injection. Instead of creating a separate <env-entry>, you can configure the greeting value using XML straight from the resin-web.xml file.
resin-web.xml
<web-app xmlns="http://caucho.com/ns/resin"> <qa:TestBean xmlns:qa="urn:java:qa"> <qa:greeting>Hello, World from web.xml</qa:greeting> </qa:TestBean> </web-app>
@TransactionAttribute
Managing transactions is the primary purpose of stateless
session beans. Transactions are a more powerful version of
a synchronized
lock used to protect database integrity.
[doc|ejb-annotations.xtp#@TransactionAttribute @TransactionAttribute]
marks the transaction boundary for each business method.
==
@javax.ejb.TransactionAttribute(SUPPORTS) public String hello()
The hello()
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.
The REQUIRED transaction value starts up a new transaction if none already exists. It's used when updating database values.
TransactionAttribute | meaning |
---|---|
REQUIRED | Start a new transaction if necessary |
SUPPORTS | Don't start a new transaction, but use one if it exists |
Configuring the EJB stateless bean
<ee:Stateless>
configure the session bean
from the resin-web.xml.
The <ee:Stateless> entry will
look at the bean's annotations to enhance the class.
ejb-stateless-bean in web.xml
<web-app xmlns="http://caucho.com/ns/resin" xmlns:qa="urn:java:qa" xmlns:lang="urn:java:java.lang" xmlns:ee="urn:java:ee"> <lang:String ee:Named="greeting"> Hello, World </lang:String> <qa:TestBean> <ee:Stateless/> </qa:TestBean> </web-app>
The <qa:TestBean> can optionally configure the bean directly with its properites as described in the alternate dependency injection section.
Client
HelloServlet.java
import javax.inject.Inject; public class HelloServlet extends GenericServlet { @Inject private Hello _hello; public void service(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { PrintWriter out = res.getWriter(); out.println(_hello.hello()); } }
@EJB
The @Inject annotation tells
Resin to look for a Hello
component in the Java Injection
repository.
The servlet could also lookup the Hello bean with JNDI in the
init()
method or use an <init> configuration in the
web.xml:
alternative configuration
<web-app xmlns="http://caucho.com/ns/resin"> <servlet servlet-name="hello" servlet-class="example.HelloServlet"> <init hello="${Hello}"/> </servlet>