Uploaded image for project: 'CDI Specification Issues'
  1. CDI Specification Issues
  2. CDI-626

How should CDI.current() and CDI.getBeanManager() behave for non-CDI apps?

    • Icon: Clarification Clarification
    • Resolution: Done
    • Icon: Major Major
    • 2.0 .Final
    • None
    • None

      We did hit the following situation:
      A user installs a Spring application WAR file in TomEE. In that case we don't boot the CDI container. But the JSF Container calls CDI.current().

      How should CDI.current() behave in that case? Throwing an IllegalStateException, returning null or return a non-functional BeanManager?

      We should also define the behaviour of CDI.getBeanManager while we are at it.

            [CDI-626] How should CDI.current() and CDI.getBeanManager() behave for non-CDI apps?

            F2F decided to treat CDI.current() as IllegalStateException when CDI is not available. It's the current API behaviour.
            Javadoc needs to be clarified on that point.

            Antoine Sabot-Durand (Inactive) added a comment - - edited F2F decided to treat CDI.current() as IllegalStateException when CDI is not available. It's the current API behaviour. Javadoc needs to be clarified on that point.

            well a bit more than taste cause it implies how an application can test if CDI is there: is getCdi() enough or should it tries to call one CDI method too? Also not sure what "container" means in your comment, I see CDI as the CDI container handle so anything before is not really CDI (= the CDIProvider is a bridge to CDI but doesn't require CDI). That said agree we just need to make it clear. One point can maybe be to check the api jars out there and see if changing the impl isn't easier since people will maybe not upgrade their API :s.

            Also it viciously brings the question of the contextuality of CDIProvider which is maybe not something we want to "spec" yet (ie is the provider bound to an impl and one context once the lookup is done or is CDI only contextual?).

            Romain Manni-Bucau (Inactive) added a comment - well a bit more than taste cause it implies how an application can test if CDI is there: is getCdi() enough or should it tries to call one CDI method too? Also not sure what "container" means in your comment, I see CDI as the CDI container handle so anything before is not really CDI (= the CDIProvider is a bridge to CDI but doesn't require CDI). That said agree we just need to make it clear. One point can maybe be to check the api jars out there and see if changing the impl isn't easier since people will maybe not upgrade their API :s. Also it viciously brings the question of the contextuality of CDIProvider which is maybe not something we want to "spec" yet (ie is the provider bound to an impl and one context once the lookup is done or is CDI only contextual?).

            and fail on getBeanManager() only

            ..and also CDI.select(), CDI.destroy(), etc.

            For me the provider is responsible to lookup a "valid" container instance and it's useless to return an instance which would throw ISE on each invocation. But it's probably just a matter of taste . The EG should decide...

            Martin Kouba added a comment - and fail on getBeanManager() only ..and also CDI.select() , CDI.destroy() , etc. For me the provider is responsible to lookup a "valid" container instance and it's useless to return an instance which would throw ISE on each invocation. But it's probably just a matter of taste . The EG should decide...

            Ok so rephrased it means: when should the resolution of the CDI context occurs: in the provider or in the CDI instance. For me the provider is a hook to let the impl be plugged so I'm tempted to say we can let getCdi() be passthrough and fail on getBeanManager() only. What you called "uninitialized" could actually be "initialized" as JNDI context is active but a resource can not be bound behind a name.

            Romain Manni-Bucau (Inactive) added a comment - - edited Ok so rephrased it means: when should the resolution of the CDI context occurs: in the provider or in the CDI instance. For me the provider is a hook to let the impl be plugged so I'm tempted to say we can let getCdi() be passthrough and fail on getBeanManager() only. What you called "uninitialized" could actually be "initialized" as JNDI context is active but a resource can not be bound behind a name.

            arjant_jira Good point. I would guess that you mostly get some javax.naming.NamingException today.

            Martin Kouba added a comment - arjant_jira Good point. I would guess that you mostly get some javax.naming.NamingException today.

            Additionally, what about the bean manager obtained from JNDI? In Mojarra we use that as well (it's on my TODO list to make sure we use the same method everywhere). I haven't tried it yet, but in that case would the bean manager simply not be present in JNDI, or would a non-functional one be returned, or... ?

            Arjan t (Inactive) added a comment - Additionally, what about the bean manager obtained from JNDI? In Mojarra we use that as well (it's on my TODO list to make sure we use the same method everywhere). I haven't tried it yet, but in that case would the bean manager simply not be present in JNDI, or would a non-functional one be returned, or... ?

            Hm, I see. But if we do then a CDIProvider would have to return some "uninitialized" CDI instance anyway. So I don't see a difference here. Either CDIProvider impl or CDI impl would have to handle this. Actually, the returned CDI instance would have to handle this for all methods inherited from javax.enterprise.inject.Instance. From impl point of view, CDIProvider modification will be one method, CDI modification many methods.

            Martin Kouba added a comment - Hm, I see. But if we do then a CDIProvider would have to return some "uninitialized" CDI instance anyway. So I don't see a difference here. Either CDIProvider impl or CDI impl would have to handle this. Actually, the returned CDI instance would have to handle this for all methods inherited from javax.enterprise.inject.Instance . From impl point of view, CDIProvider modification will be one method, CDI modification many methods.

            I agree getBeanManager() should throw an exception but also means CDIProvider.getCDI() doesn't otherwise we can't call it. Moreover CDIProvider is a plain SPI today and I think it is good to keep it simple so I would put the behavior in the impl and therefore CDI only. Nice thing doing that is the API stay simple and deployment doesn't affect runtime behavior (OSGi/JBoss module or graph classloading, hierarchical classloading, flat classloading).

            Romain Manni-Bucau (Inactive) added a comment - I agree getBeanManager() should throw an exception but also means CDIProvider.getCDI() doesn't otherwise we can't call it. Moreover CDIProvider is a plain SPI today and I think it is good to keep it simple so I would put the behavior in the impl and therefore CDI only. Nice thing doing that is the API stay simple and deployment doesn't affect runtime behavior (OSGi/JBoss module or graph classloading, hierarchical classloading, flat classloading).

            I believe that both CDIProvider.getCDI() and CDI.getBeanManager() should throw an IllegalStateException. But then a user would have no easy way to determine whether a CDI container is running or not (except for catching the exception).

            Martin Kouba added a comment - I believe that both CDIProvider.getCDI() and CDI.getBeanManager() should throw an IllegalStateException . But then a user would have no easy way to determine whether a CDI container is running or not (except for catching the exception).

              asabotdu@redhat.com Antoine Sabot-Durand (Inactive)
              struberg Mark Struberg (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

                Created:
                Updated:
                Resolved: