KItis KItis - 1 month ago 6
Java Question

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

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>

Answer

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" />