ejb-spec
  1. ejb-spec
  2. EJB_SPEC-67

Improve stateful bean injection scenarios

    Details

    • Type: New Feature New Feature
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Won't Fix
    • Affects Version/s: 3.2
    • Fix Version/s: 3.2
    • Labels:
      None

      Description

      The use cases for injection of Stateful session beans into container-managed component types (Stateless, Singleton, MDBs, Servlets) are extremely limited due to the fact that injection occurs when the component class is constructed. In order to get an invocation-based stateful bean, applications must either inject and use 2.x homes or do a JNDI lookup.

      Proposal –

      Provide a type-safe interface for creating stateful session beans that is decoupled from JNDI/EJBContext lookup. The interface would be similar to 2.x-style homes but without requiring the bean provider to specify an explicit home interface.

      The interface looks something like this:

      package javax.ejb;
      
      public interface SessionFactory<T> {
        T create();
      }
      

      This interface is bound into the java:module/app/global namespace for stateful beans using this new interface.

      Example:

      • java:module/Bean!com.foo.ejb.BizIntf!javax.ejb.SessionFactory

      Example usage:

      // Stateful bean definition
      
      @Stateful
      public class MyStateful implements BizIntf {
      
        private String something;
      
        public String getSomething() {
           return something;
        }
        ...
      }
      
      // Client-side injection and EJB ref (for completeness) of factory using annotations:
      
      @Singleton
      @EJB(name="ejb/bizfactory", beanInterface=BizIntf.class, sessionFactory=true)
      public class MySingleton {
      
        @EJB
        private SessionFactory<BizIntf> factory;
      
        @Resource
        private SessionContext ctx;
      
        public myMethodInjection() {
          BizIntf biz = factory.create();
          String s =  biz.getSomething();
        }
      
        public myMethodLookup() {
          SessionFactory<BizIntf> factory = (SessionFactory<BizIntf>)ctx.lookup("ejb/bizfactory");
          BizIntf biz = factory.create();
          String s = biz.getSomething();
      }
      

      ejb-ref definition in the DD:

      <ejb-ref-name>ejb/BizIntfFactory</ejb-ref-name>
      <ejb-ref-type>SessionFactory</ejb-ref-type>
      <local>com.foo.ejb.BizIntf</local>

      Primary Motivations:
      1. Injection and type safety - Again, SFSB's can't be usefully injected into most container-managed component types, so you must use lookup, which requires a cast.
      2. Performance - eliminates the need for a lookup on each client invocation. Also decouples SFSB creation performance from JNDI, since lookup performance is limited by/bound to the performance of naming.
      3. A means for enabling use of stateless beans with OSGi service registry - Vendors are starting to experiment with EJBs in OSGi service registry, which has no mechanism for creating multiple interfaces (ServiceFactory doesn't work since it's once-per-bundle.)

      Other considerations/possible additions:
      1. A create method which takes a variable argument list(Object... args). It would not be type-safe, but would provide a path to support @Init.
      2. A RemoteSessionFactory for business RMI that throws RemoteException.
      3. A ManagedBeanFactory that provides a factory interface for @ManagedBean. Would need to find a home for that interface (!javax.annotations). Also, would require coordination with managed beans spec.

        Activity

        jrbauer created issue -
        jrbauer made changes -
        Field Original Value New Value
        Description The use cases for injection of Stateful session beans into container-managed component types (Stateless, Singleton, MDBs, Servlets) are extremely limited due to the fact that injection occurs when the component class is constructed. In order to get an invocation-based stateful bean, applications must either inject and use 2.x homes or do a JNDI lookup.

        Proposal --

        Provide a type-safe interface for creating stateful session beans that is decoupled from JNDI/EJBContext lookup. The interface would be similar to 2.x-style homes but *without* requiring the bean provider to specify an explicit home interface.

        The interface looks something like this:

        package javax.ejb;

        public interface SessionFactory<T> {
          T create();
        }

        This interface is bound into the java:module/app/global namespace for stateful beans using this new interface.

        Example:

        * java:module/Bean!com.foo.ejb.BizIntf!javax.ejb.SessionFactory

        Example usage:

        // Stateful bean definition

        @Stateful
        public class MyStateful implements BizIntf {

          private String something;

          public String getSomething() {
             return something;
          }
          ...
        }

        // Client-side injection and EJB ref (for completeness) of factory using annotations:

        @Singleton
        @EJB(name="ejb/bizfactory", beanInterface=BizIntf.class, sessionFactory=true)
        public class MySingleton {

          @EJB
          private SessionFactory<BizIntf> factory;

          @Resource
          private SessionContext ctx;

          public myMethodInjection() {
            BizIntf biz = factory.create();
            String s = biz.getSomething();
          }

          public myMethodLookup() {
            SessionFactory<BizIntf> factory = (SessionFactory<BizIntf>)ctx.lookup("ejb/bizfactory");
            BizIntf biz = factory.create();
            String s = biz.getSomething();
        }

        ejb-ref definition in the DD:

        <ejb-ref-name>ejb/BizIntfFactory</ejb-ref-name>
        <ejb-ref-type>SessionFactory</ejb-ref-type>
        <local>com.foo.ejb.BizIntf</local>

        Primary Motivations:
        1. Injection and type safety - Again, SFSB's can't be usefully injected into most container-managed component types, so you must use lookup, which requires a cast.
        2. Performance - eliminates the need for a lookup on each client invocation. Also decouples SFSB creation performance from JNDI, since lookup performance is limited by/bound to the performance of naming.
        3. A means for enabling use of stateless beans with OSGi service registry - Vendors are starting to experiment with EJBs in OSGi service registry, which has no mechanism for creating multiple interfaces (ServiceFactory doesn't work since it's once-per-bundle.)
          
        Other considerations/possible additions:
        1. A create method which takes a variable argument list(Object... args). It would not be type-safe, but would provide a path to support @Init.
        2. A RemoteSessionFactory for business RMI that throws RemoteException.
        3. A ManagedBeanFactory that provides a factory interface for @ManagedBean. Would need to find a home for that interface (!javax.annotations). Also, would require coordination with managed beans spec.

        The use cases for injection of Stateful session beans into container-managed component types (Stateless, Singleton, MDBs, Servlets) are extremely limited due to the fact that injection occurs when the component class is constructed. In order to get an invocation-based stateful bean, applications must either inject and use 2.x homes or do a JNDI lookup.

        Proposal --

        Provide a type-safe interface for creating stateful session beans that is decoupled from JNDI/EJBContext lookup. The interface would be similar to 2.x-style homes but *without* requiring the bean provider to specify an explicit home interface.

        The interface looks something like this:

        {noformat}
        package javax.ejb;

        public interface SessionFactory<T> {
          T create();
        }
        {noformat}

        This interface is bound into the java:module/app/global namespace for stateful beans using this new interface.

        Example:

        * java:module/Bean!com.foo.ejb.BizIntf!javax.ejb.SessionFactory

        Example usage:

        {noformat}
        // Stateful bean definition

        @Stateful
        public class MyStateful implements BizIntf {

          private String something;

          public String getSomething() {
             return something;
          }
          ...
        }

        // Client-side injection and EJB ref (for completeness) of factory using annotations:

        @Singleton
        @EJB(name="ejb/bizfactory", beanInterface=BizIntf.class, sessionFactory=true)
        public class MySingleton {

          @EJB
          private SessionFactory<BizIntf> factory;

          @Resource
          private SessionContext ctx;

          public myMethodInjection() {
            BizIntf biz = factory.create();
            String s = biz.getSomething();
          }

          public myMethodLookup() {
            SessionFactory<BizIntf> factory = (SessionFactory<BizIntf>)ctx.lookup("ejb/bizfactory");
            BizIntf biz = factory.create();
            String s = biz.getSomething();
        }
        {noformat}

        ejb-ref definition in the DD:

        <ejb-ref-name>ejb/BizIntfFactory</ejb-ref-name>
        <ejb-ref-type>SessionFactory</ejb-ref-type>
        <local>com.foo.ejb.BizIntf</local>

        Primary Motivations:
        1. Injection and type safety - Again, SFSB's can't be usefully injected into most container-managed component types, so you must use lookup, which requires a cast.
        2. Performance - eliminates the need for a lookup on each client invocation. Also decouples SFSB creation performance from JNDI, since lookup performance is limited by/bound to the performance of naming.
        3. A means for enabling use of stateless beans with OSGi service registry - Vendors are starting to experiment with EJBs in OSGi service registry, which has no mechanism for creating multiple interfaces (ServiceFactory doesn't work since it's once-per-bundle.)
          
        Other considerations/possible additions:
        1. A create method which takes a variable argument list(Object... args). It would not be type-safe, but would provide a path to support @Init.
        2. A RemoteSessionFactory for business RMI that throws RemoteException.
        3. A ManagedBeanFactory that provides a factory interface for @ManagedBean. Would need to find a home for that interface (!javax.annotations). Also, would require coordination with managed beans spec.

        Hide
        petermuir added a comment -

        If you are using CDI, you can use Instance<> for this.

        Show
        petermuir added a comment - If you are using CDI, you can use Instance<> for this.
        Hide
        marina vatkina added a comment -

        Pete, CDI spec says:

         
        The container must provide a built-in bean with:
        • Instance<X> and Provider<X> for every legal bean type X in its set of bean types
        

        Does it mean that the requested functionality is available now for any SFSB?

        Show
        marina vatkina added a comment - Pete, CDI spec says: The container must provide a built-in bean with: • Instance<X> and Provider<X> for every legal bean type X in its set of bean types Does it mean that the requested functionality is available now for any SFSB?
        Hide
        petermuir added a comment -

        Marina,

        Essentially yes, with the obvious requirement that CDI is enabled for the application. This also extends to SLSBs and singletons.

        There are a few cases where this wouldn't work, but in those cases the developer has added some CDI annotations to their session bean (e.g. qualifiers, alternatives, specialization).

        Show
        petermuir added a comment - Marina, Essentially yes, with the obvious requirement that CDI is enabled for the application. This also extends to SLSBs and singletons. There are a few cases where this wouldn't work, but in those cases the developer has added some CDI annotations to their session bean (e.g. qualifiers, alternatives, specialization).
        Hide
        jrbauer added a comment -

        Thanks, Pete & Marina. I'll take a closer look at CDI. It doesn't help with motivation #3 though. And, from an pure EJB perspective, there is still a void in the injection space. We promote the use of business interfaces and injection, but users need to drop back to using 2.x homes or lookup with stateful beans in order to get the behavior they want.

        Show
        jrbauer added a comment - Thanks, Pete & Marina. I'll take a closer look at CDI. It doesn't help with motivation #3 though. And, from an pure EJB perspective, there is still a void in the injection space. We promote the use of business interfaces and injection, but users need to drop back to using 2.x homes or lookup with stateful beans in order to get the behavior they want.
        Hide
        petermuir added a comment -

        @jrbauer yeah, i was really just trying to make you aware of the options

        Show
        petermuir added a comment - @jrbauer yeah, i was really just trying to make you aware of the options
        Hide
        marina vatkina added a comment -

        This is what our OSGi expert told me about SFSBs and OSGI:

        There is a lifecycle mismatch between OSGi services and EJBs. EJBs are of three types:
        stateful, stateless and singleton. OSGi has two types: per bundle and singleton. From a client view perspective, stateless and singleton are same and they can be mapped to singleton OSGi services where as there is no mapping for stateful available.

        As there is already a solution for the non-OSGi case, closing the issue.

        Show
        marina vatkina added a comment - This is what our OSGi expert told me about SFSBs and OSGI: There is a lifecycle mismatch between OSGi services and EJBs. EJBs are of three types: stateful, stateless and singleton. OSGi has two types: per bundle and singleton. From a client view perspective, stateless and singleton are same and they can be mapped to singleton OSGi services where as there is no mapping for stateful available. As there is already a solution for the non-OSGi case, closing the issue.
        marina vatkina made changes -
        Status Open [ 1 ] Resolved [ 5 ]
        Fix Version/s 3.2 [ 14833 ]
        Resolution Won't Fix [ 2 ]
        Hide
        jrbauer added a comment -

        Marina,

        Requirement 21 in the OSGi EJB RFP (https://www.osgi.org/bugzilla/show_bug.cgi?id=148) states:

        "EJB021 - The solution MUST support service registration of stateless and singleton EJBs and may support service registration of other EJB types."

        It's the "may" that this item is intended to address. Providing a session factory opens new possibilities for using EJBs in through OSGi services, especially for stateful beans.

        I know 3.2 is winding down, but I'd like to give folks a little more time to consider this item, if possible.

        Show
        jrbauer added a comment - Marina, Requirement 21 in the OSGi EJB RFP ( https://www.osgi.org/bugzilla/show_bug.cgi?id=148 ) states: "EJB021 - The solution MUST support service registration of stateless and singleton EJBs and may support service registration of other EJB types." It's the "may" that this item is intended to address. Providing a session factory opens new possibilities for using EJBs in through OSGi services, especially for stateful beans. I know 3.2 is winding down, but I'd like to give folks a little more time to consider this item, if possible.
        Hide
        jlmonteiro added a comment -

        Java EE does not target OSGi environment.
        Java EE must be kinda OSGi enabler, but the integration is definitely something under OSGI EE responsibility.

        Show
        jlmonteiro added a comment - Java EE does not target OSGi environment. Java EE must be kinda OSGi enabler, but the integration is definitely something under OSGI EE responsibility.
        Hide
        marina vatkina added a comment -

        If there is an overwhelming support for this feature, I'll reopen .

        Show
        marina vatkina added a comment - If there is an overwhelming support for this feature, I'll reopen .
        Hide
        jrbauer added a comment -

        Fair enough. Thanks, Marina.

        Show
        jrbauer added a comment - Fair enough. Thanks, Marina.

          People

          • Assignee:
            Unassigned
            Reporter:
            jrbauer
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: