User Tools

Site Tools


jboss_ejb

Creating

Creating EJBs is easy. Simply create a class with the appropriate annotations and deploy it as part of a .war or .jar.

Singleton EJB

Singletons can be useful, especially when you have big/costly resources (which probably need to be initialized at deployment, not when they are first needed). To do this add the @Singleton annotation to your class. If you want to do some initialization also add the @Startup annotation and a method annotated with @PostConstruct

Example

@Startup
@Singleton
@Lock(LockType.WRITE) // If you are unsure if your class is threadsafe, add this to forbid concurrent access.
public class RMMMapmatcher implements Mapmatcher {	
	@PostConstruct
	private void init() {
          //some initialization stuff
	}
 
        public String doSomething() {
           return "something";
        }
}

Remotely accessible EJB

Please note that 'remote' here does not only necessarily mean “remote server” but rather anything that is not in the same application (and thus has a different classloader / different class visibilities). Generally remote access can be achieved by using the @Remote annotation. However things are bit more complicated when you want to cast the bean to a usable class (JNDI lookup returns java.lang.Object):

  • 1.) create a bean-api.jar which defines the API of the EJB
    • bean-api.jar should contain the interface of the EJB and all data transfer classes
    • all data transfer classes need to be Serializable
    • the bean-api.jar will be a dependency for the EJB implementation and the EJB user
      • –> the .jar must not contain the actual EJB implementation/annotations, otherwise it will be deployed multiple times (which is probably not what you want)
  • 2.) implement the EJB in a separate .jar or .war and add the appropriate @Remote annotation:
@Startup
@Singleton
@Remote(Mapmatcher.class) //  interface from the bean-api.jar
public class RMMMapmatcher implements Mapmatcher {
 // implementation
}
  • 3.) implement the JNDI EJB lookup on the client
Object o = new InitialContext().lookup("java:global/map-service/RMMMapmatcher"); // JNDI lookup 
Mapmatcher mm = (Mapmatcher) o; // cast to interface of bean-api.jar
// use normally .. 

Using

There are several ways of using the EJB:

  • When you are inside a container managed class you can just use dependency injection (see Java CDI).
  • Anywhere else you can use JNDI to get a reference to to the class:

Lookup via JNDI

When the EJB is being deployed JBoss shows under which JNDI names it is registered. It should look something like this:

13:01:08,136 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-1) JNDI bindings for session bean named 
DefaultTraveltimeService in deployment unit deployment "traveltime-service.war" are as follows:

        java:global/traveltime-service/DefaultTraveltimeService
        java:app/traveltime-service/DefaultTraveltimeService
        java:module/DefaultTraveltimeService

Knowing this name, using the EJB is straingtforward:

DefaultTraveltimeService s = (DefaultTraveltimeService) new InitialContext().lookup("java:global/traveltime-service/DefaultTraveltimeService");

Note that JBoss registers the EJB under several names which are visible to different contexts:

  • java:global - visible to the whole application server (other .wars and .ejbs)
    Please note that just being “visible” does not imply that it is actually _usable_ without further steps. Have a look at Remotely accessible EJB.
  • java:app - visible in the same application
  • java:module - visible in the same module

see https://docs.jboss.org/author/display/AS71/JNDI+Reference for details

Additional Global JNDI names

The @EJB anntation can be used to register an EJB under addtional JNDI names:

@Stateless
@EJB(name = "java:global/MyBean", beanInterface = MyBean.class)
public class MyBean
{
}

However comining this technique with @Remote currently breaks the JNDI page in the JBoss 7.1.1 administration console.

jboss_ejb.txt · Last modified: 2013/12/23 14:01 by hkoller