Chapter 5. Enterprise Applications with EJB3 Services

EJB3 (Enterprise Java Bean 3.0) provides the core component model for Java EE 5 applications. An EJB3 bean is a managed component that is automatically wired to take advantage of all services the Java EE 5 server container provides, such as transaction, security, persistence, naming, dependency injection, etc. The managed component allows developers to focus on the business logic, and leave the cross-cutting concerns to the container as configurations. As an application developer, you need not create or destroy the components yourself. You only need to ask for an EJB3 bean from the Java EE container by its name, and then you can call its methods with all configured container services applied. You can get access to an EJB3 bean from either inside or outside of the Java EE container.
JBoss Enterprise Application Platform 5 supports EJB3 out of the box. Note that JBoss Enterprise Application Platform 4.2 is a J2EE server, so it does not support the full EJB3 feature set.
The details of the EJB3 component programming model is beyond the scope of this guide. Most EJB3 interfaces and annotations are part of the Java EE 5 standard and hence they are the same for all Java EE 5 compliant application servers. Interested readers should refer to the EJB3 specification or numerous EJB3 books to learn more about EJB3 programming.
In this chapter, we only cover EJB3 configuration issues that are specific to the JBoss Enterprise Application Platform. For instance, we discuss the JNDI naming conventions for EJB3 components inside the JBoss Enterprise Application Platform, the optional configurations for the Hibernate persistence engine for entity beans, as well as custom options in the JBoss EJB3 deployer.

5.1. Session Beans

Session beans are widely used to provide transactional services for local and remote clients. To write a session bean, you need an interface and an implementation class.

@Local
public interface MyBeanInt {
  public String doSomething (String para1, int para2);
}

@Stateless
public class MyBean implements MyBeanInt {

  public String doSomething (String para1, int para2) {
    ... implement the logic ...
  } 
  
}    

When you invoke a session bean method, the method execution is automatically managed by the transaction manager and the security manager in the server. You can specify the transactional or security properties for each method using annotations on the method. A session bean instance can be reused by many clients.
Depending on whether or not the server maintains the bean's internal state between multiple invocations coming from the same client, the session bean can be stateless or stateful. If the bean has a remote business interface clients outside of the current JVM can call the EJB3 bean. All these are configurable via standard annotations on the beans. Note that the transactional or security properties are only active when the bean is called through a business interface.
After you define a session bean, how does the client get a reference to it? As we discussed, the client does not create or destroy EJB3 components, it merely asks the server for a reference of an existing instance managed by the server. That is done via JNDI. In JBoss Enterprise Application Platform, the default local JNDI name for a session bean is dependent on the deployment packaging of the bean class.
  • If the bean is deployed in a standalone JAR file in the <JBOSS_HOME>/default/deploy directory, the bean is accessible via local JNDI name MyBean/local, where MyBean is the implementation class name of the bean as we showed earlier. The "local" JNDI in JBoss Enterprise Application Platform means that the JNDI name is relative to java:comp/env/.
  • If the JAR file containing the bean is packaged in an EAR file, the local JNDI name for the bean is myapp/MyBean/local, where myapp is the root name of the EAR archive file (e.g., myapp.ear, see later for the EAR packaging of EJB3 beans).
Of course, you should change local to remote if the bean interface is annotated with @Remote and the bean is accessed from outside of the server it is deployed on. Below is the code snippet to get a reference of the MyBean bean in a web application (e.g., in a servlet or a JSF backing bean) packaged in myapp.ear, and then invoke a managed method.

try {
  InitialContext ctx = new InitialContext();
  MyBeanInt bean = (MyBeanInt) ctx.lookup("myapp/MyBean/local");
} catch (Exception e) {
  e.printStackTrace ();
}

... ...

String result = bean.doSomething("have fun", 1);

... ...

What the client gets from the JNDI is essentially a "stub" or "proxy" of the bean instance. When the client invokes a method, the proxy figures out how to route the request to the server and marshal together the response.
If you do not like the default JNDI names, you can always specify your own JNDI binding for any bean via the @LocalBinding annotation on the bean implementation class. The JNDI binding is always "local" under the java:comp/env/ space. For instance, the following bean class definition results in the bean instances available under JNDI name java:comp/env/MyService/MyOwnName.

@Stateless
@LocalBinding (jndiBinding="MyService/MyOwnName")
public class MyBean implements MyBeanInt {

  public String doSomething (String para1, int para2) {
    ... implement the logic ...
  } 
  
}    

Note

Java EE 5 allows you to inject EJB3 bean instances directly into the web application via annotations without explicit JNDI lookup. This behavior is not yet supported in JBoss Enterprise Application Platform 5.2. However, the JBoss Enterprise Platform provides an integration framework called JBoss Seam. JBoss Seam brings EJB3 / JSF integration to new heights far beyond what Java EE 5 provides. Please see more details in the JBoss Seam Reference Guide bundled with the platform.