Announcement Announcement Module
Collapse
No announcement yet.
Forcing Dependency Injection Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Forcing Dependency Injection

    I am trying to inject a dependency into a class. The class is named TechnicianViewHelper and looks something like this:

    Code:
    public class TechnicianViewHelper {
    
        private TechnicianService technicianService;
    
        @Required
        public void setTechnicianService(TechnicianService technicianService) {
            this.technicianService = technicianService;
        }
    
        private int technicianId;
    
        public void setTechnicianId(int technicianId) {
            this.technicianId = technicianId;
        }
    
        public List<Technician> getUnapprovedTechnicians() {
            List<Technician> unapprovedTechnicianList = technicianService.getUnapprovedTechnicians();
            return unapprovedTechnicianList;
            //return technicianService.getUnapprovedTechnicians();
        }
    }
    Since this is a webapp, the related bean definitions in applicationContext.xml look something like this:

    HTML Code:
        <bean id="technicianService" class="mil.af.amc.projecttracker.service.TechnicianServiceImpl">
            <property name="technicianDao">
                <ref bean="technicianDao" />
            </property>
            <property name="personDao">
                <ref bean="personDao" />
            </property>
            <property name="gradeDao">
                <ref bean="gradeDao" />
            </property>
            <property name="baseDao">
                <ref bean="baseDao" />
            </property>
            <property name="organizationDao">
                <ref bean="organizationDao" />
            </property>
            <property name="officeSymbolDao">
                <ref bean="officeSymbolDao" />
            </property>
            <property name="permissionDao">
                <ref bean="permissionDao" />
            </property>
            <property name="projectDao">
                <ref bean="projectDao" />
            </property>
        </bean>
    
    <bean id="technicianViewHelper" class="mil.af.amc.projecttracker.web.viewhelpers.TechnicianViewHelper" depends-on="technicianService">
            <property name="technicianService">
                <ref bean="technicianService" />
            </property>
        </bean>
    I'm reasonably sure that technicianService is working correctly: my LoginAction defined in action-servlet.xml pulls the same service and works fine.

    I've also tried, in desperation, switching the technicianViewHelper to be autowired by name. But when I attempt to debug the TechnicianViewHelper class, the debug shows the technician service to be null, and a NullPointerException is thrown.

    Am I just making a stupid mistake here?

    Jason

  • #2
    You are retrieving this bean from Spring right, and not just "new TechnicianViewHelper()"?

    BTW; if the dependency is required I would consider using constructor injection.

    I would also avoid autowiring like the plague...really

    Comment


    • #3
      No, I'm definitely using Spring.

      I've changed the bean definition for technicianViewHelper to the following:

      HTML Code:
          <bean id="technicianViewHelper" class="mil.af.amc.projecttracker.web.viewhelpers.TeamViewHelper">
              <constructor-arg type="mil.af.amc.projecttracker.service.TechnicianService" index="1">
                  <ref bean="technicianService" />
              </constructor-arg>
          </bean>
      and put the following constructor into TechnicianViewHelper:

      Code:
          public TechnicianViewHelper(TechnicianService technicianService) {
              this.technicianService = technicianService;
          }
      However, the application will now not instantiate, giving the following error:


      2007-08-07 10:51:46.677 ERROR J2EE HTTP-00004 Internal error raised tyring to instantiate web-application: projecttracker defined in web site OC4J 10g (10.1.3) Default Web Site. Error creating bean with name technicianViewHelper' defined in ServletContext resource [/WEB-INF/classes/applicationContext.xml]: 1 constructor arguments specified but no matching constructor found in bean 'technicianViewHelper' (hint: specify index and/or type arguments for simple parameters to avoid type ambiguities)

      Again, I'm probably making silly mistakes here.

      (One more thing: TechnicianService is an interface, and the implementation is TechnicianServiceImpl, if that helps.

      Comment


      • #4
        Your bean definition is for TeamViewHelper, but your java code is for TechnicianViewHelper

        Comment


        • #5
          Okay, that scream you just heard was likely me... I must've hit the autocomplete in IDEA too quickly. Thanks for the assistance... I'm on to an entirely new exception now...

          (And I usually try to avoid autowiring because the explanation "it's magic" doesn't help the maintainers much...)

          Comment


          • #6
            Alright, back to square one... I can't use a <constructor-arg> because the TechnicanViewHelper is used in a JSP as a bean:

            HTML Code:
                <jsp:useBean id="technicianViewHelper"
                             scope="page"
                             class="mil.af.amc.projecttracker.web.viewhelpers.TechnicianViewHelper" />
            Unfortunately, jsp:useBean requires a no-argument constructor. If it weren't for that, the constructor-arg method seems to work.

            Here is the current bean definition for the TechnicianViewHelper:

            HTML Code:
                <bean id="technicianViewHelper" class="mil.af.amc.projecttracker.web.viewhelpers.TechnicianViewHelper">
                    <property name="technicianService">
                        <ref bean="technicianService" />
                    </property>
                </bean>
            Any more ideas?

            Comment


            • #7
              I think you're on to the core of the problem. jsp:useBean requires a no argument constructor, because it will use this constructor to instantiate a bean...

              Check out http://forum.springframework.org/showthread.php?t=36326.

              Comment


              • #8
                Originally posted by DartmanX2 View Post
                Alright, back to square one... I can't use a <constructor-arg> because the TechnicanViewHelper is used in a JSP as a bean:
                I generally put any beans that the view needs into the Model that the view renders.

                In other words rather than using jsp:useBean I would modify my controller to put it into the model, the view just picks it up out of the model.

                Comment

                Working...
                X