6

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

flynfish
  • 5,857
  • 3
  • 24
  • 33

6 Answers6

4

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.

Sri Sankaran
  • 8,120
  • 4
  • 38
  • 47
2

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
}
flynfish
  • 5,857
  • 3
  • 24
  • 33
  • I faced the same problem and everything worked when configured in xml. removed autowired and @service annotations from service bean emailServiceImpl. Autowiring works fine in other beans. I wonder what's wrong with autowiring in JavaMail. – Valsaraj Viswanathan Jan 26 '16 at 14:38
1

This is how I fixed it:

I ran into this issue too, I tried to follow simple tutorials online that worked perfectly during testing by loading the app-context.xml file manually but when I tried to run my spring mvc app it kept showing this error:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [org.springframework.mail.javamail.JavaMailSender] 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)}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:952)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:821)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:735)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:478)
    ... 42 more

After trying all kinds of things, I happened to move these two lines from my JPA/DB configuration file to the bottom of my root-config file.

<context:annotation-config/>           
<context:component-scan base-package="my.app.service.layer"/>

I'm still learning Spring but I'm thinking there was an issue regarding the order in which they appear.

Edit: This question seems to clarify the issue with the order:

Difference between applicationContext.xml and spring-servlet.xml in Spring Framework

Community
  • 1
  • 1
Ulises
  • 13,229
  • 5
  • 34
  • 50
1

You need to add <context:annotation-config/> to your config file in order for Spring to autowire annotated beans.

http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-annotation-config

Travis
  • 336
  • 1
  • 5
  • I have tried that and it gives the same error. I will add it back in to my original post. Any other ideas? – flynfish Dec 27 '11 at 17:59
  • There are 2 other things you could try. Add another line in your xml for specify where to scan for your bean and also try setting the autowire-candidate attribute to true on the email sender bean. – Travis Dec 27 '11 at 18:03
  • I was able to reproduce your error and the component scan should fix your issue. – Travis Dec 27 '11 at 18:21
  • I tried the component scan and autowire-candidate and unfortunately neither of those worked. I already had the component scan in root-context.xml. I also added it in the servlet-context.xml above which didn't do anything: – flynfish Dec 27 '11 at 18:27
  • What xml file was used for the code above? How many different xml files are you using? – Travis Dec 27 '11 at 18:47
  • The above is the servlet-context.xml. I added a pic of the file structure to my post. controllers.xml just has a context:component scan for the package.name.web folder. – flynfish Dec 27 '11 at 19:08
  • +1 thanks for all your help, I posted my solution below because I couldn't get autowire to work. – flynfish Dec 28 '11 at 20:42
1

From error message, I can conclude that autowiring is working , but its not able to find the required bean.

Make sure you load all the bean definition files.

Dhananjay
  • 3,903
  • 2
  • 29
  • 44
1

Do you have a @Service or similar annotation on your JavaMailSenderImpl class itself? This will cause Spring's component scanner to put an instance of it in the spring container, which it can then autowire onto the EmailServiceImpl.

Jon Riegel
  • 21
  • 2