3 Replies Latest reply on Feb 24, 2015 1:18 PM by tremes

    RequestScoped beans in MessageDriven beans in wildfly

    poths

      Hi dear wildfly community,

       

      I am using Wildfly 8.1.0 and expected the calls to MessageDriven beans having an open RequestScope so that I could inject my EntityManager via a RequestScoped provider.

       

      Unfortunately I get the exception:

       

      Caused by: org.jboss.weld.context.ContextNotActiveException: WELD-001303: No active contexts for scope type javax.enterprise.context.RequestScoped

        at org.jboss.weld.manager.BeanManagerImpl.getContext(BeanManagerImpl.java:680)

        at org.jboss.weld.manager.BeanManagerImpl.getReference(BeanManagerImpl.java:733)

        at org.jboss.weld.injection.producer.AbstractMemberProducer.getReceiver(AbstractMemberProducer.java:128)

        at org.jboss.weld.injection.producer.AbstractMemberProducer.produce(AbstractMemberProducer.java:148)

        at org.jboss.weld.bean.AbstractProducerBean.create(AbstractProducerBean.java:183)

        at org.jboss.weld.context.unbound.DependentContextImpl.get(DependentContextImpl.java:69)

        at org.jboss.weld.manager.BeanManagerImpl.getReference(BeanManagerImpl.java:733)

        at org.jboss.weld.manager.BeanManagerImpl.getReference(BeanManagerImpl.java:789)

        [...]

       

      My message driven class looks roughly like this:


      @MessageDriven(

              activationConfig = {

                     @ActivationConfigProperty(propertyName = "destinationLookup", propertyValue = "jms/OfferTopic"),

                     @ActivationConfigProperty( propertyName = "destinationType"propertyValue = "javax.jms.Topic") })

      @Transactional

      public class TestMessageReceiver implements MessageListener {

       

          @Inject

          private EntityManager em;

       

          @Override

          public void onMessage(Message message) {

              ...

          }

      }


      I can add more information if needed, but feel I might be completely on the wrong path. So here are my questions:

      1. Is the assumption correct, that I should have a request scope in the message driven bean? If not, in which CDI scope would I keep an entity manager?
      2. Can I programmatically create the request scope inside an Interceptor? I found some JBoss 7.1.2 code that seems to do this but I have a hard time reproducing this: http://grepcode.com/file/repo1.maven.org/maven2/org.jboss.as/jboss-as-weld/7.1.2.Final/org/jboss/as/weld/ejb/EjbRequestS…

       

      Thank you very much for any hints into a better direction.

        • 1. Re: RequestScoped beans in MessageDriven beans in wildfly
          tremes

          Hi Mathias,

           

          What do you mean by " I could inject my EntityManager via a RequestScoped provider"? Do you have your custom CDI producer for EntityManager? I don't fully understand but it's not good idea to have RequestScoped EntityManager. You can check http://docs.oracle.com/javaee/7/tutorial/persistence-intro003.htm#BNBQW and Contexts and Dependency Injection for the Java EE platform. I am sorry but I don't understand the second question much as well. What would you like to do? The code you refered to is JBoss Weld integration code which is not good source as an example.    

          1 of 1 people found this helpful
          • 2. Re: Re: RequestScoped beans in MessageDriven beans in wildfly
            poths

            Hi Tomas,

             

            thank you so much for the nice reply and sorry my request might have been confusing. I'll try to make it more clear.

             

            Situation

            You concluded correctly that I started to use a custom RequestScoped provider in order to be able to replace it via CDI for unit tests. This is why I do not just use @PersistenceContext inside all the beans.

             

            @RequestScoped

            public class EntityManagerProvider {

               

                @PersistenceContext(unitName="default")

                private EntityManager entityManager;

             

                @Produces

                public EntityManager getEntityManager() {

                    return entityManager;

                }

            }

             

            Then I inject the EntityManager with just an @Inject annotation in my JAX-RS service beans which works well, but on the JMS Beans it fails with the above message as there is no RequestScope.


            My current understanding

            So I understand that there is no need for a RequestScope during JMS calls from your point of view. You say " it's not good idea to have RequestScoped EntityManager", so what would you recommend to be safe that no transactions influence each other? I feel the above construct with the RequestScoped provider is what I found used most often.


            If I understand the information on the websites you linked so, that the above EntityManagerProvider should work if I just change the @RequestScoped into @Dependent annotation, right? I tried it and it looks pretty good so far, I get injected a TransactionScopedEntityManager. Maybe I just wanted to be too much in control of the scope of the EntityManagerProvider.

             

            One last question, then I think I might have a way better picture of the whole story: What will happen if I now had a case where this I inject this EntityManager into an ApplicationScoped bean? Will this still work and CDI takes care of the `magic` or can I run into concurrency issues then?

             

            Sorry, I really have a hard time wrapping my brain around the CDI scopes and want to make sure I have a proper setup here.

             

            Thanks again for your time and help,

            Mathias

            • 3. Re: Re: Re: RequestScoped beans in MessageDriven beans in wildfly
              tremes

              Ok so which container and which Weld version do you use? I still don't understand much what would you like to achieve. Do you want to use different EntityManager for your tests? Because I don't understand why you don't simply use this inside your MDB:

              @PersistenceContext
              private EntityManager entityManager;
              

               

              Note that the code you provided doesn't produce any @RequestScoped EntityManager, but the @Dependent scoped. In other words - producers don't inherit scope from the class where they were defined. If you are interested in CDI/Weld I would recommend you to read Weld - CDI Reference Implementation and also discuss in Weld

              You can inject requestScoped bean into some applicationScoped bean - yes it will work.

              1 of 1 people found this helpful