Showing posts with label Enterprise Java Beans. Show all posts
Showing posts with label Enterprise Java Beans. Show all posts

29.5.12

EJB Lifecycle Interceptor

Depending on the actually type of your Enterprise Java Bean you can have different lifecycle events e.g. PostConstruct or PreDestroy. It is also possible to create Interceptors for these callback methods. The following code shows an EJB with a intercepted callback method and the Interceptor implementation.


@Stateful
@Interceptors({MyInterceptor.class})
public class MemberRegistration{
   
    @PostConstruct
    public void init() {
           // do smg
    }
}

public class MyInterceptor implements Serializable{

    @PostConstruct
    public Object intercept(InvocationContext ctx) throws Exception{
         // do smg
        return ctx.proceed();
    }
}

The first thing to note  is that interceptors for lifecycle events can be just declared at class level; nothing happens if the annotation is added to the method. Furthermore, a general advice, do not forget to call the proceed method on the context object (unless intended). I saw several examples without it, which results in overwriting the intercepted method.

13.2.12

EJB 3.1 Timer Service: Like a Boss

The EJB 3.1 specification introduces new additional cron-style timer service. It is now possible to define automatically created and cronjob like EJBs.

Our first simple example takes advantage of the newly introduced annotation:

@Singleton
public class MyTimer {
    @Schedule(minute="*", second="*/3", hour="*" ,persistent=false)
    public void timing(){
        System.out.println("yeah, i'm an automatic timer service");
    }
}

The @Schedule annotation allows you to define the timing behaviour of your service in details (year, month, day .... timezone). It is also possible to create combinations:

    @Schedules({
        @Schedule(minute="*", 
                  second="*/10", 
                  hour="*" ,persistent=false),
        @Schedule(minute="*", 
                  second="*/5", 
                  hour="*" ,persistent=false)
    })
    public void detailTiming(){
        System.out.println("very detailed timer service");
    }

If you want to set your timing behavior dynamically on runtime, you use a combination of the old 3.0 annotations and the newly introduced class ScheduleExpression.


@Singleton
@Startup
public class ProgramaticalTimer {

    @Resource
    private TimerService timerService;
   
    @PostConstruct
    public void init(){
        ScheduleExpression expression = new ScheduleExpression();
        expression.second("*").minute("*").hour("*");
        timerService.createCalendarTimer(expression);
    }
    @Timeout
    public void timeIt(){
        System.out.println("A bit old school.");
    }
}
As you already noticed the @Startup annotation was added; only timers marked with @Schedule are created automatically. This workaround provides the wanted behaviour in a different way.
Furthermore, according to the EJB 3.1 spec:
For automatically created timers, the timeout method may be a method that is annotated with the Schedule annotation. Timers can be created for stateless session beans, singleton session beans, message-driven beans, and 2.1 entity beans[94]. Timers cannot be created for stateful session beans[95] ... The timer service is intended for the modelling of long-lived business processes. Timers survive container crashes, server shutdown, and the activation/passivation and load/store cycles of the enterprise beans that are registered with them. These persistent guarantees can optionally be disabled on a per-timer basis.
Following values are valid for schedule properties:
  • Single Value (10)
  • Wild Card (*) 
  • List (Mon, Wed, Fri) 
  • Range(Fri-Mon) 
  • Increments(30/10)
For more detailed information take a look into the EJB 3.1 spec

8.1.12

EJB 3.x: One Interface Two Implementations

Note: This entry is about handling the issue "One Interface Two Implementations" for Enterprise Java Beans (EJB) 3.x. Fixing such a problem for the Context Dependency Injection (CDI) framework is done differently and will be covered by another entry.

Problem
If you provide two implementations within your WAR or EAR file for just one interface and inject it using this code

@EJB
private MyInterface myInterface;

the application server will complain as soon as you try to deploy your archive; e.g. Glassfish throws an exception looking something like that:

Cannot resolve reference Remote ejb-ref name=at.rt.ClientBean/myInterface,Remote 3.x interface =at.rt.sameinterface.MyInterface,ejb-link=null,lookup=,mappedName=, jndi-name=,refType=Session because there are 2 ejbs in the application with interface at.rt.sameinterface.MyInterface.

 
Solution
If you want to keep your annotation, simply use the following code to resolve the lookup problem:

@EJB(beanName="MyInterfaceOneBean")
private MyIntterface myInterface;

The other possibility is to modify your deployment descriptor and add an entry similar to that:

<ejb-jar ...>
 <enterprise-beans>
    <session>
        <ejb-name> ClientBean </ejb-name>
        <ejb-local-ref>
            <ejb-ref-name>at.rt.ClientBean/myInterface</ejb-ref-name>
            <local>at.rt.sameinterface.MyInterface </local>
            <ejb-link>MyInterfaceOneBean</ejb-link>
        </ejb-local-ref>
    </session>
</enterprise-beans>
</ejb-jar>

12.12.11

Simple EJB 3.0 Timer

Creating an EJB 3.0 Timer is pretty straight forward.
First, the TimerService is needed. It can be  retrieved direclty via Dependency Injection or using the SessionContext.

@Resource
private javax.ejb.TimerService timerSerivce;

The TimerService interface offers different methods for the creating the actual timer. Most important is the differentiation between  single-event and interval.

public void doSmg() {
     System.out.println("Create Timer");
     timerSerivce.createTimer(3000,3000,  
                            "ObjectAccessibleInTheTimeoutMethod");
}

The first parameter indicates when the timer goes off; the value must be relative, so in this case it will be executed in 3 seconds. For details on the method signatures, please refer to the API doc.
Within the same Bean a method with the following signature and annotation is needed:

@Timeout
 public void timeSomething(Timer timer) {
        System.out.println(timer.getInfo());
 }

It is executed whenever the timer goes off. The getInfo() method returns the passed serializable Object, in this case the String "ObjectAccessibleInTheTimeoutMethod".

Timer Facts:
  • Timers are persistent by specification, if the server crashes or is shutdown, created timers must still exist. However, just to get sure check your server's documentation, e.g. older JBoss servers versions delete timers after  a shutdown. Furthermore, the persisting - implementation is not specified, so this can vary too.
  • If the execution of a timer was missed, because e.g. the server was shut down, it will immediately be called after the server is back online.
  • The timer methods (annotated with @Timeout) are execeuted within a transaction.
  • Possible just for Message Driven and Stateless Session Beans

1.12.11

Java EE Interceptors

Interceptors are the pragmatic implementation of Aspect Oriented Programming within the Java EE stack. At the current version JEE 6 there exist two different technologies providing this functionality Enterprise Java Beans and Context Dependency Injection (if you have the choice, use the CDI implementation as it offers far more functionalities)

Why we want it
Interceptors are mostly used for so called cross cutting concerns (c-c) like logging, security or infrastructural code. Such concerns are, briefly speaking, occuring at very many different places in many different classes. And as programmers who care about code readability, we do not want to pollute our beautiful business logic with such stuff. Thanks to Intercepors, we can put that code for the c-c concern in some other far far away class. After that we just need to annotate classes or methods that we want to intercept. Thereby it is possible to execute our c-c code before or after the actual business logic method.

How the magic happens
Adam Bien wrote a short and simple blog entry about how to implement an EJB Interceptor, really good one. CDI interceptors can be found here.
First, the Interceptor needs to be implemented, how depends on the technology (EJB, CDI). Second, annotate the class (all methods) or specific method you want to activate the Interceptor for. Thats it. After deployment, the container always automatically runs the Interceptor before the business logic method is executed. It is as simple as that.

Criticism
It might happen that people who are not really into Java EE mechanisms will come up with following arguments against Interceptors:
  • Black Magic - As they do not really know how Interceptors work and what their benefits are, they will simple declerate them as evil.
  • Difficult to Test - Not true at all ... The logic within the Interceptor class can be Unit-tested as in any other class; simply mock the InvocationContext if necessary. Furthermore, if you want to test the actual business logic, instantiate the class and  simply invoke the Interceptor's method manually. Last but not least, the integration test of all components has to be done anyway, with or without Interceptors.
  • Difficult to trace back- It may be kind of true that if some programmer is debugging your code not knowing about the Interceptor, might have some troubles, especially if the Interceptor is just defined in XML. So a general advice would be to always annotate your intercepted classes and to avoid XML configuration. Furthermore, if you are debugging someone else's EJBs, always look out for Interceptor annotations :)
If you know more arguments against Interceptors, or have something else to add, please feel free :)