Results 1 to 8 of 8

Thread: Forcing Dependency Injection

  1. #1
    Join Date
    Aug 2007
    Posts
    28

    Default 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. #2
    Join Date
    Aug 2004
    Posts
    1,905

    Default

    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
    Colin Yates
    SpringSource - http://www.springsource.com - Spring Training, Consulting, and Support - "From the Source"
    Please read http://www.springframework.org/documentation
    Co-Author of Expert Spring MVC + Web Flow.

  3. #3
    Join Date
    Aug 2007
    Posts
    28

    Default

    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.

  4. #4
    Join Date
    Aug 2004
    Posts
    1,905

    Default

    Your bean definition is for TeamViewHelper, but your java code is for TechnicianViewHelper
    Colin Yates
    SpringSource - http://www.springsource.com - Spring Training, Consulting, and Support - "From the Source"
    Please read http://www.springframework.org/documentation
    Co-Author of Expert Spring MVC + Web Flow.

  5. #5
    Join Date
    Aug 2007
    Posts
    28

    Default

    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...)

  6. #6
    Join Date
    Aug 2007
    Posts
    28

    Default

    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?

  7. #7
    Join Date
    May 2007
    Location
    Netherlands
    Posts
    614

    Default

    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.

  8. #8
    Join Date
    Aug 2004
    Posts
    1,905

    Default

    Quote 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.
    Colin Yates
    SpringSource - http://www.springsource.com - Spring Training, Consulting, and Support - "From the Source"
    Please read http://www.springframework.org/documentation
    Co-Author of Expert Spring MVC + Web Flow.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •