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

1

5

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.

Finley answered 2/9, 2012 at 11:8 Comment(5)
Did you try using Events feature of CDI?Tumulus
e.g fire an event in EJB @PostConstruct, which is observed by your service.Tumulus
@tair no. i was not aware that i can fire CDI events for myself :) u mean i can fire events from all my EJBs on which the service relies on and then act on it? e.g. block or release the job?Finley
Yes. Another solution is to create a @Startup MyServiceEjb, which @DependsOn all the EJBs needed to run a service.Tumulus
how do you auto-start your CDI beans?Tumulus
T
8

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

Tumulus answered 3/9, 2012 at 13:14 Comment(2)
no problem, i learned by your answer about the DependsOn stuff :) well, the initial problem is, that the job started by a job scheduler starts process instances which runs in an BPMN2 process engine, and the tasks there uses EJBs. And my problem is that the process instances are executed when the EJBs are not yet in place. Maybe if i create one EJB which DependsOn the needed EJBs and then i check if that EJB is available or not? Can i do this check via JNDI? then i could add a task to my process definition which perform this check and exit gracefully.Finley
I've updated the answer with a far-fetched CDI events example, just to demo events feature. A simpler way would be to just @Inject LastBean and @PostConstruct startService() in CDIService -- this is just another way of defining startup dependenciesTumulus

© 2022 - 2024 — McMap. All rights reserved.