4 Replies Latest reply on Aug 30, 2010 2:38 AM by nimo stephan

    Constructor question

    nimo stephan Master

      According weld documentation (chapter: 1.2),
      I have not use a constructor with no paramer, when using constructor injection:



      But wait! TextTranslator does not have a constructor with no parameters! Is it still a bean? If you remember,
      a class that does not have a constructor with no parameters can still be a bean if it has a constructor annotated
      @Inject.


      Compiling this:


      @SessionScoped @Named
      public class MyBean{
              
         @PersistenceContext EntityManager entityManager;
      
          OtherBean ob;
              
      // I do not use the Constructor with no parameters
      //      public MyBean(){}  
              
              @Inject
              public MyBean(OtherBean ob){
                      
                      this.ob= ob;
      
              }
              
              public OtherBean getOb() {return ob;}
              public void setOb(OtherBean ob) {this.ob= ob;}
      }




      leads to the following error:




      ERROR: Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.0.2:testCompile (default-testCompile) on project Project: Compilation failure
      ...\Project\MyBean.java:[28,26] cannot find symbol
      symbol  : constructor MyBean()
      location: class com.MyBean






      I have to use this, in order to compile the code successfully:


      @SessionScoped @Named
      public class MyBean{
      
      @PersistenceContext EntityManager entityManager;
      
              OtherBean ob;
              
      // I have to use this Constructor additionally to the injected Constructor
              public MyBean(){}  
              
              @Inject
              public MyBean(OtherBean ob){
                      
                      this.ob= ob;
      
              }
              
              public OtherBean getOb() {return ob;}
              public void setOb(OtherBean ob) {this.ob= ob;}
      }




      So do I misunderstood that ?:




      If you remember, a class that does not have a constructor with no parameters can still be a bean if it has a constructor annotated.



      My class has not a constructor with no parameters, but it has a injected constructor (with parameters).

        • 1. Re: Constructor question
          Marius Bogoevici Newbie

          Hm, this is a compilation error. Are you sure that you're not invoking the no-arg constructor explicitely from anywhere in your code?


          Apart from that, and completely unrelated to the compilation error - and I stress that :), you may need a no-arg constructor anyway, since your bean is normal-scoped (session-scoped) - and the framework will need to be able to create a proxy for it - read chapter 5.4 of the CDI specification for details. But, even then, this would show up at deployment time and not during compilation.

          • 2. Re: Constructor question
            Jan Groth Novice

            I can confirm that the above code compiles :-)


            As Marius suggests:




            1. a compilation error should always be unrelated to any Weld issued

            2. a deployment error will be thrown by the container because MyBean is not proxyable





            org.jboss.weld.exceptions.UnproxyableResolutionException: 
            WELD-001400 Normal scoped bean org.jboss.weld.bean-flat-ManagedBean-class ...MyBean is not proxyable
                 at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:127)




            The example from the Weld-reference which you are quoting is not annotated, and therefore @dependent-scoped, which does not require the bean to be proxyable...



            public class TextTranslator {
            private SentenceParser sentenceParser;
            private Translator sentenceTranslator;
            




            • 3. Re: Constructor question
              nimo stephan Master

              Hello Marius,


              yes, you are right. I had overseen that I invoked the no-arg constructor explicitely from my Test-Code.



              So to sum up:



              When injecting constructor, should I use this:


              Version 1:


                      public MyBean(){}  
                      
                      @Inject
                      public MyBean(OtherBean ob){
                              
                              this.ob= ob;
              
                      }






              or that:



              Version 2:


               public MyBean(){}  
                      
                      // Normally (without CDI), I also need the non-arg constructor.
                      public MyBean(){}
              
                      @Inject
                      public MyBean(OtherBean ob){
                              
                              this.ob= ob;
              
                      }



              In CDI, both versions work. Which version should I use? Does it make a difference?

              • 4. Re: Constructor question
                nimo stephan Master



                you may need a no-arg constructor anyway, since your bean is normal-scoped (session-scoped)


                Okay, so I need to use version 2. However, using version 1 does not return a deployment error.