Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException:

177,356

Solution 1

Use component scanning as given below, if com.project.action.PasswordHintAction is annotated with stereotype annotations

<context:component-scan base-package="com.project.action"/>

EDIT

I see your problem, in PasswordHintActionTest you are autowiring PasswordHintAction. But you did not create bean configuration for PasswordHintAction to autowire. Add one of stereotype annotation(@Component, @Service, @Controller) to PasswordHintAction like

@Component
public class PasswordHintAction extends BaseAction {
    private static final long serialVersionUID = -4037514607101222025L;
    private String username;

or create xml configuration in applicationcontext.xml like

<bean id="passwordHintAction" class="com.project.action.PasswordHintAction" />

Solution 2

You need to provide a candidate for autowire. That means that an instance of PasswordHint must be known to spring in a way that it can guess that it must reference it.

Please provide the class head of PasswordHint and/or the spring bean definition of that class for further assistance.

Try changing the name of

PasswordHintAction action;

to

PasswordHintAction passwordHintAction;

so that it matches the bean definition.

Share:
177,356
KItis
Author by

KItis

software engineer

Updated on January 01, 2021

Comments

  • KItis
    KItis over 3 years

    I am creating web application using Spring, Hibernate, Struts, and Maven.

    I get the below error when I run mvn clean install command:

    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.project.action.PasswordHintActionTest': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.project.action.PasswordHintAction com.project.action.PasswordHintActionTest.action; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.project.action.PasswordHintAction] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    

    The following is the class that has the Autowired dependency:

    import com.opensymphony.xwork2.Action;
    import org.project.model.User;
    import org.proejct.service.UserManager;
    import org.junit.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.subethamail.wiser.Wiser;
    
    import static org.junit.Assert.*;
    public class PasswordHintActionTest extends BaseActionTestCase {
        @Autowired
        private PasswordHintAction action;
        @Autowired
        private UserManager userManager;
    
        @Test
        public void testExecute() throws Exception {
            // start SMTP Server
            Wiser wiser = new Wiser();
            wiser.setPort(getSmtpPort());
            wiser.start();
    
            action.setUsername("user");
            assertEquals("success", action.execute());
            assertFalse(action.hasActionErrors());
    
            // verify an account information e-mail was sent
            wiser.stop();
            assertTrue(wiser.getMessages().size() == 1);
    
            // verify that success messages are in the request
            assertNotNull(action.getSession().getAttribute("messages"));
        }
    
    
    }
    

    My applicationcontext.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"
           default-lazy-init="true">
    
        <!-- Activates scanning of @Autowired -->
        <context:annotation-config/>
    
        <!-- Activates scanning of @Repository and @Service -->
        <context:component-scan base-package="com.project"/>
    
        <!-- Compass Search Section -->
        <!-- Compass Bean, automatically scanning for searchable classes within the model -->
        <!-- Hooks into Spring transaction management and stores the index on the file system -->
        <bean id="compass" class="org.compass.spring.LocalCompassBean">
            <property name="mappingScan" value="org.project"/>
            <property name="postProcessor" ref="compassPostProcessor"/>
            <property name="transactionManager" ref="transactionManager" />
            <property name="settings">
                <map>
                    <entry key="compass.engine.connection" value="target/test-index" />
                </map>
            </property>
        </bean>
    

    I have added to my context configuration to scan Autowired dependencies. But I am not sure why it is still giving this exception.

    I tried adding it in following way also but I still get the same exception

    <context:component-scan base-package="com.project.*"/>
    

    UPDATE:

    following is the password hint action

    import org.project.model.User;
    import com.project.webapp.util.RequestUtil;
    import org.springframework.mail.MailException;
    import org.springframework.security.core.userdetails.UsernameNotFoundException;
    
    import java.util.ArrayList;
    import java.util.List;
    
    
    public class PasswordHintAction extends BaseAction {
        private static final long serialVersionUID = -4037514607101222025L;
        private String username;
    
        /**
         * @param username The username to set.
         */
        public void setUsername(String username) {
            this.username = username;
        }
    
        /**
         * Execute sending the password hint via e-mail.
         *
         * @return success if username works, input if not
         */
        public String execute() {
            List<Object> args = new ArrayList<Object>();
    
            // ensure that the username has been sent
            if (username == null) {
                log.warn("Username not specified, notifying user that it's a required field.");
    
                args.add(getText("user.username"));
                addActionError(getText("errors.requiredField", args));
                return INPUT;
            }
    
            if (log.isDebugEnabled()) {
                log.debug("Processing Password Hint...");
            }
    
            // look up the user's information
            try {
                User user = userManager.getUserByUsername(username);
                String hint = user.getPasswordHint();
    
                if (hint == null || hint.trim().equals("")) {
                    log.warn("User '" + username + "' found, but no password hint exists.");
                    addActionError(getText("login.passwordHint.missing"));
                    return INPUT;
                }
    
                StringBuffer msg = new StringBuffer();
                msg.append("Your password hint is: ").append(hint);
                msg.append("\n\nLogin at: ").append(RequestUtil.getAppURL(getRequest()));
    
                mailMessage.setTo(user.getEmail());
                String subject = '[' + getText("webapp.name") + "] " + getText("user.passwordHint");
                mailMessage.setSubject(subject);
                mailMessage.setText(msg.toString());
                mailEngine.send(mailMessage);
    
                args.add(username);
                args.add(user.getEmail());
    
                saveMessage(getText("login.passwordHint.sent", args));
            } catch (UsernameNotFoundException e) {
                log.warn(e.getMessage());
                args.add(username);
                addActionError(getText("login.passwordHint.error", args));
                getSession().setAttribute("errors", getActionErrors());
                return INPUT;
            } catch (MailException me) {
                addActionError(me.getCause().getLocalizedMessage());
                getSession().setAttribute("errors", getActionErrors());
                return INPUT;
            }
    
            return SUCCESS;
        }
    }
    

    Update 2:

    applicationContext-struts.xml:

    <bean id="passwordHintAction" class="com.project.action.PasswordHintAction" scope="prototype">
        <property name="userManager" ref="userManager"/>
        <property name="mailEngine" ref="mailEngine"/>
        <property name="mailMessage" ref="mailMessage"/>
    </bean>