5

I m using Spring Boot 2.0.0.BUILD-SNAPSHOT. I have a problem when autowiring JavaMailSender or JavaMailSenderImpl. If i configure @Autowired for JavaMailSender, i m getting below error.

***************************
APPLICATION FAILED TO START
***************************

Description:

Field mailSender in com.hm.assetmanagment.service.MailService required a bean of type 'org.springframework.mail.javamail.JavaMailSenderImpl' that could not be found.
    - Bean method 'mailSender' not loaded because @ConditionalOnClass did not find required class 'javax.mail.internet.MimeMessage'

Action:

Consider revisiting the conditions above or defining a bean of type 'org.springframework.mail.javamail.JavaMailSenderImpl' in your configuration.

Below are my pom.xml which has spring boot starter email.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.hm.assetmanagement</groupId>
    <artifactId>AssetManagementSystem</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>AssetManagementSystem</name>
    <description>AssetManagementSystem</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.0.BUILD-SNAPSHOT</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!-- <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-rest</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity4</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- <dependency> 
            <groupId>javax.mail</groupId> 
            <artifactId>mail</artifactId> 
            <version>1.4.7</version> 
        </dependency>-->

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
            <!-- <exclusions>
            <exclusion>                  
                <groupId>com.sun.mail</groupId>
                <artifactId>javax.mail</artifactId>
            </exclusion>
        </exclusions>-->
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </pluginRepository>
        <pluginRepository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>

</project>

package com.hm.assetmanagment.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MailService {

    @Autowired
    private JavaMailSenderImpl mailSender;

    @RequestMapping("/assets/allocateemail/{name}/{email}/{assetid}")
    private void sendAssetAllocationEmail(String name, String email, String assetid) {
        /*SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
        simpleMailMessage.setTo(email);
        simpleMailMessage.setSubject("Asset Allocation Confirmation");
        simpleMailMessage.setText("Hello " + name + "," + assetid + "\n" + " - Asset allocated to you");
        mailSender.send(simpleMailMessage);*/

    }
}

I tried by adding javax.mail jar/spring context support manually in dependency but it didnt work.

application.properties:
spring.mail.host=smtp.gmail.com
spring.mail.username=xxx@gmail.com
spring.mail.password=xxx
spring.mail.port=587

spring.h2.console.enabled=true
spring.h2.console.path=/h2-console

spring.thymeleaf.cache=false
debug=true

spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

Main Class:
package com.hm.assetmanagment;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

@EnableJpaRepositories
@SpringBootApplication
public class AssetManagementSystemApplication {

    public static void main(String[] args) {
        SpringApplication.run(AssetManagementSystemApplication.class, "--debug");
        //SpringApplication.run(AssetManagementSystemApplication.class, args);
    }
}

Please guide.

Update from me Nov22:

If i create new class and enable auto configuration on that class, JavaMailSender and JavaMailSenderImpl are autowired properly and spring boot application starts successfully. Already i have enableautoconfiguration in application.class as well. Is it fine to have two classes configured with enableautoconfiguration? Is there any other way to autowire JavaMailSender?

@EnableAutoConfiguration
public class MailConfig {

    @Autowired
    private JavaMailSenderImpl mailSender;
}
user2057006
  • 617
  • 4
  • 15
  • 28

3 Answers3

7

well it looks like you have not configured the Mailer at all , thus Spring cannot find the bean in order to wire it. If it was a dependency issue , then you would get a ClassNotFoundException or NoClassDefException , which is not your case. Anyway try to configure your Mailer like this :

@Configuration 
public class MailConfig {

    @Bean
    public JavaMailSender javaMailService() {
        JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();

        javaMailSender.setHost("myHost");
        javaMailSender.setPort(25);

        javaMailSender.setJavaMailProperties(getMailProperties());

        return javaMailSender;
    }

    private Properties getMailProperties() {
        Properties properties = new Properties();
        properties.setProperty("mail.transport.protocol", "smtp");
        properties.setProperty("mail.smtp.auth", "false");
        properties.setProperty("mail.smtp.starttls.enable", "false");
        properties.setProperty("mail.debug", "false");
        return properties;
    }
}

Original answer here

Community
  • 1
  • 1
AntJavaDev
  • 1,204
  • 1
  • 18
  • 24
  • 1
    @AntJavaDev-Thanks for your response. Is it mandatory to create configuration class and create JavaMailSender instance through annotated Bean from javaMailService method? Don't spring boot starter mail create and autowire by itself without creating additional configuration class? – user2057006 Nov 21 '16 at 02:59
  • 1
    well from the latest documentation and if you check the original answer that i posted ,Spring Boot should configure it automatically by simply adding the specified parameters to the application.properties. But as i can see many having troubles setting that up , the simplest solution is to define it by yourself. – AntJavaDev Nov 21 '16 at 07:38
  • also check this [post](http://stackoverflow.com/questions/22483407/send-emails-with-spring-by-using-java-annotations) also , because it might be related to your issue. Anyway have you tried to define it as a configuration to see if thats was the issue ? Otherwise if this wont work too , then you might have a dependency mixture for the `javax.mail` jar – AntJavaDev Nov 21 '16 at 08:12
  • yes. I tried to define it as Configuration but it doesnt work. Let me check about dependency mixture and come back soon. – user2057006 Nov 21 '16 at 09:12
  • yes i got the same error if i define it as configuration – user2057006 Nov 21 '16 at 10:54
  • wow then there is an issue with the `javax.mail` dependency , double check your exported app , in the lib directory if there is any version conflict. – AntJavaDev Nov 21 '16 at 11:18
  • @AntJavaDev- I deleted .m2 repository and created a fresh spring boot project with version 1.4.2 release. Now JavaMailSender is auto configured successfully. Seriously was not able to figure out what went wrong last time with spring 2.0.0 snapshot version :( – user2057006 Nov 22 '16 at 03:05
1

By seeing your code , you need to add below properties to work

Sample app.yml file spring mail: default-encoding: UTF-8 host: localhost port: 8025 protocol: smtp test-connection: false properties.mail.smtp: starttls.enable: true


Here is the reference 
https://docs.spring.io/spring-boot/docs/2.1.x/reference/html/boot-features-email.html

make sure you are reading app properties

user1388547
  • 121
  • 1
  • 2
0

Change

@Autowired
private JavaMailSenderImpl mailSender;

to

@Autowired
private JavaMailSender mailSender;

The reason for this is, that by default Spring creates JDK proxies, if a bean class implements an interface. The JDK proxy implements the same interfaces as the bean class, but does not extend the class.

dunni
  • 43,386
  • 10
  • 104
  • 99
  • Thanks for your response. I tried autowired on JavaMailSender already but it was giving same start up failed issue. Do i need to create separate class with annotate with configuration and create JavaMailSender with annotated Bean tag? Don't spring boot starter mail, create JavaMailSender and inject it byself? – user2057006 Nov 21 '16 at 02:56
  • Can you show the code of your main application class? – dunni Nov 21 '16 at 07:13
  • added MainClass Code. – user2057006 Nov 21 '16 at 07:20