glassfish
  1. glassfish
  2. GLASSFISH-17989

EJB Container doesn't use default constructor while instantiating of a session bean

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 3.1.1
    • Fix Version/s: 3.1.2_b17
    • Component/s: ejb_container
    • Labels:
      None

      Description

      I have a simple stateless session bean class with two constructors. The first one is default constructor without parameters. The second one has one parameter. The constructors are not annotated with @Inject annotation. When EJB Container instantiates the bean, it uses constructor with one parameter. But this is against the specification JSR 299:

      If a bean class does not explicitly declare a constructor using @Inject, the constructor that accepts no parameters is the bean constructor.

      Here are my sample classes:

      MyBean.java
      @Stateless
      public class MyBean {
          public MyBean() {
              System.out.println("default constructor");
          }
          public MyBean(MyClass myObject) {
              System.out.println("constructor with parameter");
          }
      }
      
      MyBean2.java
      @Singleton
      @Startup
      public class MyBean2 {    
          @EJB
          private MyBean bean;    
          @PostConstruct
          private void postConstruct() {
              System.out.println("Bean: " + bean);
          }
      }
      

      P.S. If I add a second parameter to my constructor with parameter, an exception will be thrown:

       java.lang.VerifyError: (class: my/package/__EJB31_Generated__MyBean__Intf____Bean__, method: <init> signature: ()V) Expecting to find integer on stack
      	at java.lang.Class.getDeclaredConstructors0(Native Method)
      	at java.lang.Class.privateGetDeclaredConstructors(Class.java:2389)
      	at java.lang.Class.getConstructor0(Class.java:2699)
      	at java.lang.Class.newInstance0(Class.java:326)
      	at java.lang.Class.newInstance(Class.java:308)
      	at com.sun.ejb.containers.BaseContainer.instantiateOptionalEJBLocalBusinessObjectImpl(BaseContainer.java:3861)
      	at com.sun.ejb.containers.StatelessSessionContainer.initializeHome(StatelessSessionContainer.java:253)
      	at com.sun.ejb.containers.ContainerFactoryImpl.createContainer(ContainerFactoryImpl.java:167)
      	at org.glassfish.ejb.startup.EjbApplication.loadContainers(EjbApplication.java:230)
      	at org.glassfish.ejb.startup.EjbDeployer.load(EjbDeployer.java:290)
      	at org.glassfish.ejb.startup.EjbDeployer.load(EjbDeployer.java:101)
      	at org.glassfish.internal.data.ModuleInfo.load(ModuleInfo.java:186)
      	at org.glassfish.internal.data.ApplicationInfo.load(ApplicationInfo.java:257)
      	at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:461)
      	at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:240)
      	at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:382)
      	at com.sun.enterprise.v3.admin.CommandRunnerImpl$1.execute(CommandRunnerImpl.java:355)
      	at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:370)
      	at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1064)
      	at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1200(CommandRunnerImpl.java:96)
      	at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1244)
      	at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1232)
      	at com.sun.enterprise.v3.admin.AdminAdapter.doCommand(AdminAdapter.java:459)
      	at com.sun.enterprise.v3.admin.AdminAdapter.service(AdminAdapter.java:209)
      	at com.sun.grizzly.tcp.http11.GrizzlyAdapter.service(GrizzlyAdapter.java:168)
      	at com.sun.enterprise.v3.server.HK2Dispatcher.dispath(HK2Dispatcher.java:117)
      	at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:238)
      	at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:828)
      	at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:725)
      	at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019)
      	at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)
      	at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
      	at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
      	at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
      	at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
      	at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
      	at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
      	at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
      	at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
      	at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
      	at java.lang.Thread.run(Thread.java:619)
      

        Activity

        Hide
        marina vatkina added a comment -

        I cannot reproduce the error - EJB container never calls non-default constructor. Please attach the test case that reproduces the problem and reopen the issue

        Show
        marina vatkina added a comment - I cannot reproduce the error - EJB container never calls non-default constructor. Please attach the test case that reproduces the problem and reopen the issue
        Hide
        Volodja Medvid added a comment -

        I throw a RuntimeException in non-default constructor. If I deploy this test case to GlassFish Server Open Source Edition 3.1.1 (build 12) the exception will be thrown:

        java.lang.RuntimeException: non-default constructor called
        	at beans.MyBean.<init>(MyBean.java:15)
        	at beans.__EJB31_Generated__MyBean__Intf____Bean__.<init>(Unknown Source)
        	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
        	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
        	at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
        	at java.lang.Class.newInstance0(Class.java:355)
        	at java.lang.Class.newInstance(Class.java:308)
        	at com.sun.ejb.containers.BaseContainer.instantiateOptionalEJBLocalBusinessObjectImpl(BaseContainer.java:3861)
        	at com.sun.ejb.containers.StatelessSessionContainer.initializeHome(StatelessSessionContainer.java:253)
        	at com.sun.ejb.containers.ContainerFactoryImpl.createContainer(ContainerFactoryImpl.java:167)
        	at org.glassfish.ejb.startup.EjbApplication.loadContainers(EjbApplication.java:230)
        	at org.glassfish.ejb.startup.EjbDeployer.load(EjbDeployer.java:290)
        	at org.glassfish.ejb.startup.EjbDeployer.load(EjbDeployer.java:101)
        	at org.glassfish.internal.data.ModuleInfo.load(ModuleInfo.java:186)
        	at org.glassfish.internal.data.ApplicationInfo.load(ApplicationInfo.java:257)
        	at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:461)
        	at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:240)
        	at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:382)
        	at com.sun.enterprise.v3.admin.CommandRunnerImpl$1.execute(CommandRunnerImpl.java:360)
        	at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:370)
        	at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1064)
        	at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1200(CommandRunnerImpl.java:96)
        	at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1244)
        	at org.glassfish.deployment.autodeploy.AutoOperation.run(AutoOperation.java:145)
        	at org.glassfish.deployment.autodeploy.AutoDeployer.deploy(AutoDeployer.java:575)
        	at org.glassfish.deployment.autodeploy.AutoDeployer.deployAll(AutoDeployer.java:461)
        	at org.glassfish.deployment.autodeploy.AutoDeployer.run(AutoDeployer.java:389)
        	at org.glassfish.deployment.autodeploy.AutoDeployer.run(AutoDeployer.java:380)
        	at org.glassfish.deployment.autodeploy.AutoDeployService$1.run(AutoDeployService.java:209)
        	at java.util.TimerThread.mainLoop(Timer.java:512)
        	at java.util.TimerThread.run(Timer.java:462)
        

        With GlassFish Server Open Source Edition 3.1.2-b13 (build 13) I have the same problem.

        Show
        Volodja Medvid added a comment - I throw a RuntimeException in non-default constructor. If I deploy this test case to GlassFish Server Open Source Edition 3.1.1 (build 12) the exception will be thrown: java.lang.RuntimeException: non-default constructor called at beans.MyBean.<init>(MyBean.java:15) at beans.__EJB31_Generated__MyBean__Intf____Bean__.<init>(Unknown Source) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) at java.lang.reflect.Constructor.newInstance(Constructor.java:513) at java.lang.Class.newInstance0(Class.java:355) at java.lang.Class.newInstance(Class.java:308) at com.sun.ejb.containers.BaseContainer.instantiateOptionalEJBLocalBusinessObjectImpl(BaseContainer.java:3861) at com.sun.ejb.containers.StatelessSessionContainer.initializeHome(StatelessSessionContainer.java:253) at com.sun.ejb.containers.ContainerFactoryImpl.createContainer(ContainerFactoryImpl.java:167) at org.glassfish.ejb.startup.EjbApplication.loadContainers(EjbApplication.java:230) at org.glassfish.ejb.startup.EjbDeployer.load(EjbDeployer.java:290) at org.glassfish.ejb.startup.EjbDeployer.load(EjbDeployer.java:101) at org.glassfish.internal.data.ModuleInfo.load(ModuleInfo.java:186) at org.glassfish.internal.data.ApplicationInfo.load(ApplicationInfo.java:257) at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:461) at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:240) at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:382) at com.sun.enterprise.v3.admin.CommandRunnerImpl$1.execute(CommandRunnerImpl.java:360) at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:370) at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1064) at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1200(CommandRunnerImpl.java:96) at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1244) at org.glassfish.deployment.autodeploy.AutoOperation.run(AutoOperation.java:145) at org.glassfish.deployment.autodeploy.AutoDeployer.deploy(AutoDeployer.java:575) at org.glassfish.deployment.autodeploy.AutoDeployer.deployAll(AutoDeployer.java:461) at org.glassfish.deployment.autodeploy.AutoDeployer.run(AutoDeployer.java:389) at org.glassfish.deployment.autodeploy.AutoDeployer.run(AutoDeployer.java:380) at org.glassfish.deployment.autodeploy.AutoDeployService$1.run(AutoDeployService.java:209) at java.util.TimerThread.mainLoop(Timer.java:512) at java.util.TimerThread.run(Timer.java:462) With GlassFish Server Open Source Edition 3.1.2-b13 (build 13) I have the same problem.
        Hide
        marina vatkina added a comment -

        The error is in local beans

        Show
        marina vatkina added a comment - The error is in local beans
        Hide
        Cheng Fang added a comment - - edited

        bean constructor with params should only be invoked by
        ejb container if it's annotated with @Inject and CDI is enabled. Otherwise, the default no-arg
        constructor is used.

        Relevant part of CDI spec (JSR 299):
        3.7.1. Declaring a bean constructor
        The bean constructor may be identified by annotating the constructor @Inject.
        ...
        If a bean class does not explicitly declare a constructor using @Inject, the constructor that accepts no parameters is the
        bean constructor.

        Show
        Cheng Fang added a comment - - edited bean constructor with params should only be invoked by ejb container if it's annotated with @Inject and CDI is enabled. Otherwise, the default no-arg constructor is used. Relevant part of CDI spec (JSR 299): 3.7.1. Declaring a bean constructor The bean constructor may be identified by annotating the constructor @Inject. ... If a bean class does not explicitly declare a constructor using @Inject, the constructor that accepts no parameters is the bean constructor.
        Hide
        Cheng Fang added a comment -
        • What is the impact on the customer of the bug?

        How likely is it that a customer will see the bug and how serious is the bug?
        Is it a regression? Does it meet other bug fix criteria (security, performance, etc.)?

        Moderate impact on customers. Customers will see this bug in certain applications where bean classes
        contain multiple constructors. Not related to security or performance.
        Not a regression.

        • What is the cost/risk of fixing the bug?

        How risky is the fix? How much work is the fix? Is the fix complicated?

        The fix is low risk and not complicated, approximately 1 person day of work.

        • Is there an impact on documentation or message strings?
          No.
        • Which tests should QA (re)run to verify the fix did not destabilize GlassFish?
          Regular QA tests. I will augument ejb devtests.
        • Which is the targeted build of 3.1.2 for this fix?
          b15.
        Show
        Cheng Fang added a comment - What is the impact on the customer of the bug? How likely is it that a customer will see the bug and how serious is the bug? Is it a regression? Does it meet other bug fix criteria (security, performance, etc.)? Moderate impact on customers. Customers will see this bug in certain applications where bean classes contain multiple constructors. Not related to security or performance. Not a regression. What is the cost/risk of fixing the bug? How risky is the fix? How much work is the fix? Is the fix complicated? The fix is low risk and not complicated, approximately 1 person day of work. Is there an impact on documentation or message strings? No. Which tests should QA (re)run to verify the fix did not destabilize GlassFish? Regular QA tests. I will augument ejb devtests. Which is the targeted build of 3.1.2 for this fix? b15.
        Hide
        Cheng Fang added a comment -

        Committed revision 51901. to trunk.

        Show
        Cheng Fang added a comment - Committed revision 51901. to trunk.
        Hide
        Cheng Fang added a comment -

        Committed revision 51903. to 3.1.2 branch.

        Show
        Cheng Fang added a comment - Committed revision 51903. to 3.1.2 branch.

          People

          • Assignee:
            Cheng Fang
            Reporter:
            Volodja Medvid
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: