Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Bean Autowiring error

I am trying to implement email functionality in my app but I keep getting

No matching bean of type [org.springframework.mail.javamail.JavaMailSenderImpl] found for dependency:  expected at least 1 bean which qualifies as autowire candidate for this dependency.

Can anyone point out what I am doing incorrectly?

The xml config for the bean is:

<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"   
xsi:schemaLocation="
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />
<context:annotation-config/>
//...other stuff

<beans:bean id="mailSession" class="org.springframework.jndi.JndiObjectFactoryBean">
    <beans:property name="jndiName" value="EmailServer" />
</beans:bean>

<beans:bean id="emailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
    <beans:property name="session" ref="mailSession"/>
</beans:bean>

EmailServiceImpl class:

@Service
public class EmailServiceImpl implements EmailService {

    @Autowired
    private JavaMailSenderImpl emailSender; 

    //more code..
}

project_structure

like image 847
flynfish Avatar asked Dec 27 '11 17:12

flynfish


People also ask

Why is @autowired not working?

When @Autowired doesn't work. There are several reasons @Autowired might not work. When a new instance is created not by Spring but by for example manually calling a constructor, the instance of the class will not be registered in the Spring context and thus not available for dependency injection.

How do I resolve Beancreationexception in Spring?

To diagnose this type of issue, we'll first make sure the bean is declared: either in an XML configuration file using the <bean /> element. or in a Java @Configuration class via the @Bean annotation. or is annotated with @Component, @Repository, @Service, @Controller, and classpath scanning is active for that package.

What is Spring bean Autowiring?

The Spring framework enables automatic dependency injection. In other words, by declaring all the bean dependencies in a Spring configuration file, Spring container can autowire relationships between collaborating beans. This is called Spring bean autowiring.

Why Autowired is giving null?

The field annotated @Autowired is null because Spring doesn't know about the copy of MileageFeeCalculator that you created with new and didn't know to autowire it.


2 Answers

I was struggling with this very problem for an email service class coded like:

@Service("emailService")
public class EmailService {
  @Autowired private JavaMailSenderImpl mailSender;
  ...
  public void send(...) {
    // send logic
  }
}

I stumbled across a solution while reading about a related topic. The key point is that JavaMailSender interface is defined in the applicationContext.xml as the Spring JavaMailSenderImpl class.

Step 1: The application context file was modified to include the following bean definition:

<bean id="mailSender" 
   class="org.springframework.mail.javamail.JavaMailSenderImpl"
  p:host="myMailserver.mycompany.com" />

Step 2: The email service class was modified to look like:

@Service("emailService")
public class EmailService {
  @Autowired private JavaMailSender mailSender;   // Observe the change in the type
  ...

Voila! Spring is happy. I would though like to hear a proper explanation of the original error.

like image 176
Sri Sankaran Avatar answered Oct 06 '22 21:10

Sri Sankaran


Thanks to everyone for their responses. I was unable to get the autowiring to work, but I got the overall email solution to work by doing the following:

  1. setup the mailSession in weblogic, with a jndi name of "myMailSession"

add to servlet-context.xml:

<beans:bean id="mailSession" class="org.springframework.jndi.JndiObjectFactoryBean">
    <beans:property name="jndiName" value="myMailSession" />
</beans:bean>

<beans:bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
    <beans:property name="session" ref="mailSession"/>
</beans:bean>

<beans:bean id="emailServiceImpl" class="com.name.here.business.EmailServiceImpl">
  <beans:property name="mailSender" ref="mailSender"/>
</beans:bean>

add to web.xml:

<resource-ref>
   <description>the email session</description>
   <res-ref-name>myMailSession</res-ref-name>
   <res-type>javax.mail.Session</res-type>
   <res-auth>Container</res-auth>
</resource-ref> 

add to weblogic.xml:

<resource-description>
  <res-ref-name>myMailSession</res-ref-name>
  <jndi-name>myMailSession</jndi-name>
</resource-description>

EmailServiceImpl:

@Service
public class EmailServiceImpl implements EmailService {

    private JavaMailSender mailSender;

    public void setMailSender(JavaMailSender mailSender) {
        this.mailSender = mailSender;
    }
    //..other code
}
like image 33
flynfish Avatar answered Oct 06 '22 21:10

flynfish