Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java EE 6: controlling startup of managed beans with dependencies: CDI, EJB

I just read the very nice explanation of the various managed beans and their relations on Java EE 6 @javax.annotation.ManagedBean vs. @javax.inject.Named vs. @javax.faces.ManagedBean and as i face a annoying problem in my application i want to know if it is possible to control or influence the way how and when beans are started.

In my Java EE application I use EJB, CDI and JSF2 as view technology. Via SPI a service from a third party is booted and it configures a job executor which starts jobs and handles other timer relevant stuff. One job is immediately executed when the job executor finished its bootstrapping. This job uses CDI inject to get access to some beans and one of these beans make use of an EJB.

The problem is now that most of the time the Java EE 6 server (JBoss 7.1.1) starts the EJB is still not available then the job tries to access it. An exceptions is thrown and the job fails and the service is build to deactivate that failed job. Well, deactivating a faild job seems to be not too bad. The only solution for the job to get up and running again is to undeploy it and to redeploy it again. Which is a manual task unfortunately and it can not be done programmatically.

And, to make things bad: in rare cases this does not happen.

So, my question now is: can i somehow control the initialisation and deployment of the EJB and CDI beans so that i can ensure that all EJB beans are initialzed before the CDI beans are initialized?

I have set initialize-in-order to true in the EARs application.xml and set the sequence of the EJBs so that they get initialized they way i need them (EJB core, then EJB business, then WAR), but the CDI based service is placed as JAR in the lib folder.

like image 405
Joysn Avatar asked Sep 02 '12 11:09

Joysn


People also ask

What is a CDI managed bean?

But what is a CDI bean? A CDI bean is a POJO, plain old java object, that has been automatically instantiated by the CDI container, and is injected into all, and any qualifying injection points in the application. The CDI container initiates the bean discovery process during deployment.

What is EJB dependency injection?

EJB 3.0 specification provides annotations, which can be applied on fields or setter methods to inject dependencies. EJB Container uses the global JNDI registry to locate the dependency. Following annotations are used in EJB 3.0 for dependency injection. @EJB − used to inject other EJB reference.

What is Weld CDI?

Weld is the reference implementation of CDI: Contexts and Dependency Injection for the Java EE Platform - a JCP standard for dependency injection and contextual lifecycle management and one of the most important and popular parts of the Java EE.

What are the EJB annotations?

Annotations were introduced in Java 5.0. The purpose of having annotations is to attach additional information in the class or a meta-data of a class within its source code. In EJB 3.0, annotations are used to describe configuration meta-data in EJB classes.


1 Answers

Excerpt from Java EE 6 Tutorial with some modifications:

@Singleton
@Startup
public class BeanA { ... }

@Qualifier
@Target({FIELD, PARAMETER})
@Retention(RUNTIME)
public @interface EjbStarted {}

@Singleton
@Startup
@DependsOn("BeanA", "BeanB", "BeanC")
public class LastBean {
    @Inject @EjbStarted Event<String> event;

    @PostConstruct
    public void startService() {
        // At this moment PrimaryBean is ready for use
        event.fire("LastBean");
    }
}

public class CDIService {
    public void start(@Observes @EjbStarted String name) {
        if("LastBean".equals(name)) {
            startService();
        }
    }
}

UPDATE: While thinking about the problem, I somehow forgot that you want the initialization order in CDI beans, so the answer is somewhat out of context, sorry about that :)

UPDATE 2: Added how to make a CDI service start after EJBs

like image 198
Tair Avatar answered Jan 01 '23 13:01

Tair