7 Replies Latest reply on Mar 8, 2018 8:59 AM by Patrick Reinhart

    Accessing CDI from within a custom SubSystem

    Patrick Reinhart Newbie

      Hi everybody,

       

      I wanted to create a custom subsystem in order to fire CDI events upon before a deployment unit is being undeployed, suspended or resumed. At the current stage I will get the correct callback events from the SuspendedController and the DeploymentUnitProcessor. Now I did not found a simple code example to hook into the weld deployment processor to get hold on the deployment units javax.enterprise.event.Event object or appropriate event sink object so far.

       

      Can anyone give me some advice or point me to some code with similar functionality?

       

      Thanks for any advice

       

      Patrick

        • 1. Re: Accessing CDI from within a custom SubSystem
          Matej Novotny Novice

          Hi,

           

          I am not sure I follow what is it you need from CDI?

          From your post I gather you already managed to get hold of the information that some deployment was undeployed/suspended/resumed.

           

          If you have a custom module, you should still be able to use CDI inside (given that your module.xml declares dependency on it), hence you should be able to @Inject Event.

          Or am I misunderstanding you?

          • 2. Re: Accessing CDI from within a custom SubSystem
            Patrick Reinhart Newbie

            I try to be describe you as simple as possible, what I've done so far:

            I implemented an org.jboss.as.server.deployment.DeploymentUnitProcessor using the deploy(DeploymentPhaseContext) method to add an org.jboss.as.server.suspend.ServerActivity to the respective DeploymentUnit's org.jboss.as.server.suspend.SuspendController. Thats the way I actually get the hold on the suspend events that I like to use to signal each DeploymentUnit to be able to halt services that are still running and be able to access other beans before the container stops them.

             

            Now my idea is to send an CDI event from the ServerActivity context at the time the I get the preSuspend(ServerActivityCallback) event and before I signal done() on the passed in callback object something like this:

             

              @Override

              public void preSuspend(ServerActivityCallback listener) {

                javax.enterprise.event.Event<LifecycleEvent> eventSink = ....;

                eventSink.fire(LifecycleEvent.preSusspend());

                listener.done();

              }

             

            The problem is now how to get correctly wire the javax.enterprise.event.Event with each DeploymentUnit, what I do not know to do correctly...

            • 3. Re: Accessing CDI from within a custom SubSystem
              Martin Kouba Master

              Hi Patrick,

              A simple question - who is going to observe those lifecycle events?

              • 4. Re: Accessing CDI from within a custom SubSystem
                Matej Novotny Novice

                Can you please elaborate on the purpose/goal of this?

                 

                From what I understand, you will have this static module which will fire CDi events on each app deploy/undeploy.

                And you will then have 1 or more actual deployed applications (such as WARs) which will all have observers for these events?

                 

                If that's the case, you might not even need the Event bean for given deployment unit.

                • 5. Re: Accessing CDI from within a custom SubSystem
                  Patrick Reinhart Newbie

                  The actual problem I'm trying to solve is that I need to get informed within a CDI bean for instance before it's Deployment Unit get's into a state where I can no longer access other beans or fire events due to the stopped/suspended application. In my case I got an internal work dispatcher that will stop dispatch more jobs from this point on and wait for the existing tasks to be completed.

                   

                  When I get the @PreDestroy event I can no longer invoke any bean method or fire any events due to a no specialized EE event to handle such an state as the @PrePassivate event of an statefull bean.

                  • 6. Re: Accessing CDI from within a custom SubSystem
                    Matej Novotny Novice

                    Hmm, how about just observing @Destroyed(ApplicationScoped.class) for in Weld this happens when the app is going to shutdown (otherwise this scope is active all the time). You should still be able to do some juggling with beans at that point I guess.

                     

                    As for how to fire events in your static module approach... have you tried the (obvious) way of injecting Event<YourPayload> into your module, firing the events and observing it in your app?

                    Of course this mandates that YourPayload is known to both, your module and your deployed app.

                    I am not sure it's going to be as simple as that, but it might be worth a shot.

                    • 7. Re: Accessing CDI from within a custom SubSystem
                      Patrick Reinhart Newbie

                      Unfortunately an EJB session bean does not observe the ApplicationScoped class event objects. When you look at log file I would like to execute some action between the two log lines basically:

                       

                      14:56:10,042 INFO  [org.jboss.as.server] (management-handler-thread - 1) WFLYSRV0236: Suspending server with no timeout.

                      14:56:10,045 INFO  [org.jboss.as.ejb3] (management-handler-thread - 1) WFLYEJB0493: EJB subsystem suspension complete