Giter Club home page Giter Club logo

spring-boot-email-tools's Introduction

Spring Boot Email Tools

A set of services and tools for sending emails in a Spring Boot application using plain text, html or a template engine to generate dynamic content.

Source Website: github.com/ozimov/spring-boot-email-tools

Latest Release: 1.0.0
Latest Artifacts: it.ozimov:spring-boot-email-core, it.ozimov:spring-boot-freemarker-email, it.ozimov:spring-boot-mustache-email, it.ozimov:spring-boot-pebble-email, it.ozimov:spring-boot-thymeleaf-email
Continuous Integration:
Maven Central
Build Status codecov.io Codacy Badge

codecov.io

Background

The project relies on a templateless module it.ozimov:spring-boot-email-core that provides the core features (e.g. sending emails, scheduling and prioritizing, persistence). Since it is templateless, it does not provide any implementation of the service to be used to generate the body of the email via template engine.

If you want to use one of the template engines supported by this project (i.e. Freemarker, Mustache, Pebble and Thymeleaf), you can use the dedicated templatefull module that is shipped with the core module. The standard naming for the templatefull module is it.ozimov:spring-boot-{template_engine_name}-email (where {template_engine_name} is for instance pebble).

Dependency

Latest release is 1.0.0. To use the core module, you can import the following dependency in Maven

<dependency>
    <groupId>it.ozimov</groupId>
    <artifactId>spring-boot-email-core</artifactId>
    <version>1.0.0</version>
</dependency>

To embed the module that includes the Freemarker template engine, you can use the following Maven dependency:

<dependency>
    <groupId>it.ozimov</groupId>
    <artifactId>spring-boot-freemarker-email</artifactId>
    <version>1.0.0</version>
</dependency>

for Mustache:

<dependency>
    <groupId>it.ozimov</groupId>
    <artifactId>spring-boot-mustache-email</artifactId>
    <version>1.0.0</version>
</dependency>

for Pebble:

<dependency>
    <groupId>it.ozimov</groupId>
    <artifactId>spring-boot-pebble-email</artifactId>
    <version>1.0.0</version>
</dependency>

and for Thymeleaf:

<dependency>
    <groupId>it.ozimov</groupId>
    <artifactId>spring-boot-thymeleaf-email</artifactId>
    <version>1.0.0</version>
</dependency>

Remember that if you import the template-full module, the core module should not be required.

Usage

In your main Spring Boot application, you need to add the annotation @EnableEmailTools to enable support for all the services and controllers defined in the Spring Boot Email module, e.g.:

@SpringBootApplication
@EnableEmailTools
public class MainApplication  {

    public static void main(final String ... args) {
        SpringApplication.run(MainApplication.class, args);
    }
}

in you application.properties set the configuration needed to send the emails, e.g. if you want to send the emails using a Gmail account you can set:

spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username[email protected]
spring.mail.password=V3ry_Str0ng_Password
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true

Plus, the additional properties must be added to prevent using the persistence layer

spring.mail.scheduler.persistence.enabled=false
spring.mail.scheduler.persistence.redis.embedded=false
spring.mail.scheduler.persistence.redis.enabled=false

To send an email, use the EmailService in your Spring Boot application. E.g.

@Autowired
public EmailService emailService;

public void sendEmailWithoutTemplating(){
   final Email email = DefaultEmail.builder()
        .from(new InternetAddress("[email protected]", "Marco Tullio Cicerone "))
        .to(Lists.newArrayList(new InternetAddress("[email protected]", "Pomponius Attĭcus")))
        .subject("Laelius de amicitia")
        .body("Firmamentum autem stabilitatis constantiaeque eius, quam in amicitia quaerimus, fides est.")
        .encoding("UTF-8").build();

   emailService.send(email);
}

The previous code will send a plain text message. To obtain some more dynamic fancy emails, you have two options: i) the former and easier-to-use is to use a templatefull module (e.g. based on Freemarker); ii) the latter (which requires some effort on your side) needs an implementation of the interface it.ozimov.springboot.templating.mail.service.TemplateService.

The aforementioned interface requires a component that implements the following method

String mergeTemplateIntoString(String templateReference, Map<String, Object> model)
            throws IOException, TemplateException;

Assuming you opted for one of the previous options, just put the template in the required folder (e.g. templates under resourses) and try to execute the following code (it works with Freemarker):

@Autowired
public EmailService emailService;

public void sendEmailWithTemplating(){
   Arrays.asList(new Cospirator("[email protected]", "Gaius Cassius Longinus"),
            new Cospirator("[email protected]", "Marcus Iunius Brutus Caepio"))
        .stream.forEach(tyrannicida -> {
       final Email email = DefaultEmail.builder()
            .from(new InternetAddress("[email protected]", "Gaius Iulius Caesar"))
            .to(Lists.newArrayList(new InternetAddress(tyrannicida.getEmail(), tyrannicida.getName())))
            .subject("Idus Martii")
            .body("")//Empty body
            .encoding("UTF-8").build();
        //Defining the model object for the given Freemarker template
        final Map<String, Object> modelObject = new HashMap<>();
        modelObject.put("tyrannicida", tyrannicida.getName());

       emailService.send(email, "idus_martii.ftl", modelObject);
   };
}

private static class Cospirator {
  private String email;
  private String name;
  public Cospirator(final String email, final String name){
    this.email = email;
    this.name = name;
  }

  //getters
}

where the template idus_martii.ftl is a Freemarker file like:

<!doctype html>
<html>
	<body>
		<p>
			Tu quoque, <em>${tyrannicida}</em>!
		</p>
	</body>
</html>

The following example shows how to send and email that includes an inline image.

@Autowired
public EmailService emailService;

public void sendEmailWithTemplatingAndInlineImage(){
       final Email email = DefaultEmail.builder()
            .from(new InternetAddress("[email protected]", "Gaius Iulius Caesar"))
            .to(Lists.newArrayList(new InternetAddress("[email protected]", "Marcus Iunius Brutus Caepio")))
            .subject("Idus Martii")
            .body("")//Empty body
            .encoding("UTF-8").build();
       //Defining the model object for the given Freemarker template
       final Map<String, Object> modelObject = new HashMap<>();
       final File imageFile = //load your picture here, e.g. "my_image.jpg"
       modelObject.put("tyrannicida", tyrannicida.getName());

       final InlinePicture inlinePicture = DefaultInlinePicture.builder()
                               .file(imageFile)
                               .imageType(ImageType.JPG)
                               .templateName("my_image.jpg").build());

       emailService.send(email, "idus_martii.ftl", modelObject, inlinePicture);
}

where the template idus_martii.ftl is a Freemarker file like:

<!doctype html>
<html>
	<body>
		<p>
			<img src="my_image.jpg" />
		</p>
	</body>
</html>

be sure that the name provided in the InlinePicture matches with the one used in the template file path included, if any was set. This means that if in the template you have <img src="images/my_image.jpg" /> then the definition has to be changed as follows:

final InlinePicture inlinePicture = DefaultInlinePicture.builder()
        .file(imageFile)
        .imageType(ImageType.JPG)
        .templateName("images/my_image.jpg").build());

This is required to set the a proper content-id.

Email scheduling

The library supports email scheduling, but since version 1.0.0 the scheduler is disabled by default. To enable email scheduling, the following property has to be provided:

spring.mail.scheduler.enabled=true

Email can be set in different queues, from the one with highest priority to the least important. Priority 1 is the highest.

To define the number of priority levels to be used in the scheduler, just add in the application.properties the following line:

spring.mail.scheduler.priorityLevels=5

If not provided, by default 10 priority levels are considered.

Scheduling an email is actually easy and the EmailSchedulerService allows to schedule an email with or without the use of a template engine.

In order to schedule a plain text email, just create your service (or controller) where you autowire the service EmailSchedulerService and call a method scheduleEmail defined as in the following example

@Service
public void MyEmailSenderService {

    @Autowired
    private EmailSchedulerService EmailSchedulerService;
    
    
    public void scheduleEmail() throws CannotSendEmailException {
        final Email mimeEmail = DefaultEmail.builder()
                                  .from(new InternetAddress("[email protected]", "Gaius Iulius Caesar"))
                                  .to(Lists.newArrayList(new InternetAddress(tyrannicida.getEmail(), tyrannicida.getName())))
                                  .subject("Idus Martii")
                                  .body("Sic semper...")
                                  .encoding("UTF-8")
                                  .build();
        final OffsetDateTime scheduledDateTime = OffsetDateTime.now().plusDays(1);
        final int priorityLevel = 1;
      EmailSchedulerService.schedule(mimeEmail, scheduledDateTime, priorityLevel);
    }
}

Here we go, by calling schedulerEmail() an email has been scheduled to be sent after one day. When scheduling emails, observe that OffsetDateTime must be used with UTC, so do not forget to convert it if you use a different zone offset.

To schedule an email with a template and inline images, just call a new method called scheduleEmailWithTemplate()

@Service
public void MyEmailWithTemplateSenderService {

    @Autowired
    private EmailSchedulerService EmailSchedulerService;
    
    
    public void scheduleEmailWithTemplate() throws CannotSendEmailException {
        final Email mimeEmail = DefaultEmail.builder()
                                  .from(new InternetAddress("[email protected]", "Gaius Iulius Caesar"))
                                  .to(Lists.newArrayList(new InternetAddress(tyrannicida.getEmail(), tyrannicida.getName())))
                                  .subject("Idus Martii")
                                  .body("")//Empty body
                                  .encoding("UTF-8")
                                  .build();
       //Defining the model object for the given Freemarker template
       final Map<String, Object> modelObject = new HashMap<>();
       final File imageFile = //load your picture here, e.g. "my_image.jpg"
       modelObject.put("tyrannicida", tyrannicida.getName());

       final InlinePicture inlinePicture = DefaultInlinePicture.builder()
                               .file(imageFile)
                               .imageType(ImageType.JPG)
                               .templateName("my_image.jpg").build();
        final OffsetDateTime scheduledDateTime = OffsetDateTime.now().plusDays(1);
        final int priorityLevel = 1;
      
        EmailSchedulerService.schedule(mimeEmail, scheduledDateTime, priorityLevel, 
            "idus_martii.ftl", modelObject, inlinePicture);
    }
    
}

Persistence

Persistence has been introduced in version 0.4.0. Persistence is mainly of interest if the scheduler is used, therefore it can be enabled only if the scheduler is enabled.

The persistence layer is optional, thus needs to be activated. The default implementation is fully based on embedded REDIS. To enable the default persistence layer just add the additional properties in your application.properties file:

spring.mail.scheduler.persistence.enabled=true
spring.mail.scheduler.persistence.redis.enabled=true
spring.mail.scheduler.persistence.redis.embedded=true
spring.mail.scheduler.persistence.redis.host=localhost
spring.mail.scheduler.persistence.redis.port=6381
spring.mail.scheduler.persistence.redis.settings=

I recommend to specify in the REDIS settings at least the appendfilename and dir properties, so that you know where the append file is placed and which name it uses. For instance do:

spring.mail.scheduler.persistence.redis.settings=appendfilename email_appendonly.aof, dir /Users/your_username/Downloads

By default we have the setting appendonly yes and appendfsync everysec. Feel free to override them or fine tune them according with your needs.

Clearly, you can provide your own persistence layer by implementing the PersistenceService interface. You can also use your REDIS implementation, but this will require extra coding on your side.

Observe that the persistence layer makes the emails being stored to be reloaded on application startup if not yet sent. In particular, the emails are loaded when scheduler is constructed.

###Impact of the Persistence layer on the default priority-based scheduler The default scheduler is PriorityQueueEmailSchedulerService, which by default stores everything in memory. Clerarly, having thousands email being scheduled, storing everything in memory could drive to a potential OutOfMemoryException. Enabling the persistence layer should allow to use REDIS for persisting scheduled emails. Anyway, you may want to customize the behavior of the scheduler when interacting with the persistence layer, you can use the following params:

spring.mail.scheduler.persistence.desiredBatchSize=200
spring.mail.scheduler.persistence.minKeptInMemory=100
spring.mail.scheduler.persistence.maxKeptInMemory=1000

The first defines the maximum amount of emails being loaded from the persistence layer when a slot is available in the priority queues; the second amount is the wish for the minimum amount of emails available in memory: the third defines the amount of emails to be kept in memory. Clearly, these two values impact the response time of the scheduler. The less you store in memory, the more it takes to send the next email. The smaller is the batch size, the higher the times you interact with the persistence layer.

Customize email logging

Very often, you want to log the email that you just sent or scheduled, but you would like to avoid a full toString of the given email object. For instance, you may want to anonymize an email address, or to ignore custom headers. Here follows a list of properties you can use with some examples:

spring.mail.logging.enabled=true

spring.mail.logging.strategy.from=PLAIN_TEXT
spring.mail.logging.strategy.replyTo=HIDDEN
spring.mail.logging.strategy.to=FULL_TEXT_FROM_COMMERCIAL_AT,
spring.mail.logging.strategy.cc=HIDDEN
spring.mail.logging.strategy.bcc=HIDDEN
spring.mail.logging.strategy.subject=PLAIN_TEXT
spring.mail.logging.strategy.body=FIRST_DOZEN_THEN_STARS
spring.mail.logging.strategy.attachments=HIDDEN
spring.mail.logging.strategy.encoding=HIDDEN
spring.mail.logging.strategy.locale=HIDDEN
spring.mail.logging.strategy.sentAt=STANDARD_DATE_FORMAT_WITH_ZONE_ID
spring.mail.logging.strategy.receiptTo=HIDDEN
spring.mail.logging.strategy.depositionNotificationTo=HIDDEN
spring.mail.logging.strategy.ignore.customHeaders=true
spring.mail.logging.strategy.ignore.nullAndEmptyCollections=true

Allowed logging strategies are defined in the enum it.ozimov.springboot.mail.logging.LoggingStrategy. Do not pretend to apply a date-only strategy to an email address, or an email address-only strategy to a text field. Usage should be straightforward.

Future plans

See open issues.

Any contribution is welcome (and warmly encouraged).

License

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

How to open an issue

Are you experiencing an issue? Please, post a question on StackOverflow or open an issue on GitHub.

Issues that are not reporting a minimal set of info to reproduce the bug will be closed with no further comments.

Information that should be provided for investigations:

  • version used
  • pom.xml
  • application.properties
  • exception stacktrace
  • Are the provided examples run with success?

==============================================

forthebadge forthebadge forthebadge forthebadge

spring-boot-email-tools's People

Contributors

gmmazzeo avatar joanjanku2000 avatar lpmi-13 avatar robertotru avatar whamtet avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

spring-boot-email-tools's Issues

Error when adding @EnableEmailTools annotation on BootApplication class

ERROR 4256 --- [ restartedMain] o.s.b.d.LoggingFailureAnalysisReporter :


APPLICATION FAILED TO START


Description:

Parameter 0 of method redisTemplate in org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration$RedisConfiguration required a bean of type 'org.springframework.data.redis.connection.RedisConnectionFactory' that could not be found.
- Bean method 'redisConnectionFactory' not loaded because @ConditionalOnExpression (#{'${spring.mail.scheduler.enabled:false}' == 'true' && '${spring.mail.scheduler.persistence.enabled:false}' == 'true' && '${spring.mail.scheduler.persistence.redis.enabled:false}' == 'true' && '${spring.mail.scheduler.persistence.redis.embedded:false}' == 'true'}) resulted in false
- Bean method 'redisConnectionFactory' not loaded because @ConditionalOnClass did not find required class 'org.apache.commons.pool2.impl.GenericObjectPool'

Action:

Consider revisiting the conditions above or defining a bean of type 'org.springframework.data.redis.connection.RedisConnectionFactory' in your configuration.

Unable to attach files to the email messages

Whenever I try to send email with attachment via EmailService, I receive following exception:

java.lang.IllegalStateException: Not in multipart mode - create an appropriate MimeMessageHelper via a constructor that takes a 'multipart' flag if you need to set alternative texts or add inline elements or attachments.
	at org.springframework.mail.javamail.MimeMessageHelper.checkMultipart(MimeMessageHelper.java:383)
	at org.springframework.mail.javamail.MimeMessageHelper.getRootMimeMultipart(MimeMessageHelper.java:400)
	at org.springframework.mail.javamail.MimeMessageHelper.addAttachment(MimeMessageHelper.java:998)
	at org.springframework.mail.javamail.MimeMessageHelper.addAttachment(MimeMessageHelper.java:1077)
	at it.ozimov.springboot.templating.mail.utils.EmailToMimeMessage.apply(EmailToMimeMessage.java:80)
	at it.ozimov.springboot.templating.mail.service.EmailServiceImpl.toMimeMessage(EmailServiceImpl.java:124)
	at it.ozimov.springboot.templating.mail.service.EmailServiceImpl.send(EmailServiceImpl.java:81)
...

I tried both plain text messages or created from Freemaker template, in both cases result is the same.

Code snippet:

@ActiveProfiles("service-test")
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ServicesTestsConfiguration.class)
@TestPropertySource(locations = "classpath:application-test.properties")
public class MailTest {

    @Autowired
    public EmailService emailService;

    @Value("${mail.from}")
    private String emailFrom;

    @Value("${mail.to}")
    private String emailTo;

    private final Charset charset = Charset.forName("UTF-8");

    @Test
    public void testMail() throws AddressException, CannotSendEmailException {
        final String testData = "col1,col2\n1,2\n3,4";
        final EmailAttachmentImplBuilder attachment = EmailAttachmentImpl.builder().attachmentName("test.csv")
                .attachmentData(testData.getBytes(charset)).mediaType(MediaType.TEXT_PLAIN);
        final Email email = EmailImpl.builder().from(new InternetAddress(emailFrom)).to(Lists.newArrayList(new InternetAddress(emailTo)))
                .subject("subject").body("").encoding(charset).attachments(Lists.newArrayList(attachment.build())).build();

        final Map<String, Object> modelObject = Maps.newHashMap();
        modelObject.put("instance", "FooBar");

        // doesn't work neither: emailService.send(email);
        emailService.send(email, "email_test.ftl", modelObject);
    }

}

Thanks for looking into the issue,
Maciej

Callback on Schedule before sending a mail

Hello there,

I'm thinking about using your implementation for our project, but - alas! - one feature seems to be missing. When scheduling mails I need a callback that get's called before the mail has actually been sent to decide whether I send this email or not (for these kind of "Long time no see!"-Mails). Is this some feature which is considered for one of the next releases? Otherwise I'm thinking about issuing a pull request!

Cheers!

Strange behavior regarding attachment in DefaultEmailService using templates

When you send a message using DefaultEmailService.send(email, template, modelObject, inlinePictures), attachments are included twice in the message:

  • The first time through method "DefaultEmailService.toMimeMessage", using Spring MimeMessageHelper.
  • The second time at line 120, this time not using Spring MimeMessageHelper. This code is probably wrong, as the comment line 121 relates to image parts, not attachments.

Oddly, this does not cause the attachments to be added twice in the final email, but because MimeMessageHelper is not called the second time, MimeUtility.encodeText is not applied on attachment filename, which results in attachment filename to be missing in my case.

Workaround: call MimeUtility.encodeText myself:
DefaultEmailAttachment.builder().attachmentName(MimeUtility.encodeText(filename)))

I guess some refactoring related to inlinePictures and attachments would help :)

Fail to send templated emails without attachments

Latest spring-boot-email-tools release (0.3.7) fails to send template base emails, without attachments:

java.lang.NullPointerException
	at it.ozimov.springboot.templating.mail.service.EmailServiceImpl.send(EmailServiceImpl.java:107)

Code to reproduce:

@ActiveProfiles("service-test")
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ServicesTestsConfiguration.class)
@TestPropertySource(locations = "classpath:application-test.properties")
public class MailTest {

    @Autowired
    public EmailService emailService;

    @Value("${mail.from}")
    private String emailFrom;

    @Value("${mail.to}")
    private String emailTo;

    private final Charset charset = Charset.forName("UTF-8");

    @Test
    public void testMail() throws AddressException, CannotSendEmailException {
         final Email email = EmailImpl.builder().from(new InternetAddress(emailFrom)).to(Lists.newArrayList(new InternetAddress(emailTo)))
                .subject("subject").body("").encoding(charset).build();

        final Map<String, Object> modelObject = Maps.newHashMap();
        modelObject.put("instance", "FooBar");

        emailService.send(email, "email_test.ftl", modelObject);
    }
}

Workaround - use empty list of attachments:

final Email email = EmailImpl.builder().from(new InternetAddress(emailFrom)).to(Lists.newArrayList(new InternetAddress(emailTo)))
                .subject("subject").body("").encoding(charset).attachments(Lists.newArrayList()).build();

Thread beans for Consumer/Resumer

To increase the readability and testability of the default scheduler, Resumer and Consumer should be beans. The scope should be prototype. It should be clarified what to do for the common queue.

No qualifying bean of type 'it.ozimov.springboot.mail.service.EmailService' available

WARN 6496 --- [ main] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'simpleMimeEmailWithThymeleafApplication': Unsatisfied dependency expressed through field 'simpleThymeleafEmailService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'simpleThymeleafEmailService': Unsatisfied dependency expressed through field 'emailService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'it.ozimov.springboot.mail.service.EmailService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

Error using Thymeleaf Email Template - Invocation of init method failed; nested exception is java.lang.IllegalStateException: There is not picture images%5cgalaxy.jpeg - Windows OS

`2017-05-09 19:53:09.663 INFO 9332 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
2017-05-09 19:53:10.612 WARN 9332 --- [ main] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mimeEmailWithThymeleafApplication': Invocation of init method failed; nested exception is java.lang.IllegalStateException: There is not picture images%5cgalaxy.jpeg
2017-05-09 19:53:10.618 INFO 9332 --- [ main] o.apache.catalina.core.StandardService : Stopping service Tomcat
2017-05-09 19:53:10.639 INFO 9332 --- [ main] utoConfigurationReportLoggingInitializer :

Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2017-05-09 19:53:10.652 ERROR 9332 --- [ main] o.s.boot.SpringApplication : Application startup failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mimeEmailWithThymeleafApplication': Invocation of init method failed; nested exception is java.lang.IllegalStateException: There is not picture images%5cgalaxy.jpeg
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:137) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:409) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1620) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:370) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:314) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1162) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1151) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at com.test.MimeEmailWithThymeleafApplication.main(MimeEmailWithThymeleafApplication.java:29) [classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_66]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_66]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_66]
at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_66]
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147) [idea_rt.jar:na]
Caused by: java.lang.IllegalStateException: There is not picture images%5cgalaxy.jpeg
at com.google.common.base.Preconditions.checkState(Preconditions.java:518) ~[guava-21.0.jar:na]
at com.test.TestService.createGalaxyInlinePicture(TestService.java:59) ~[classes/:na]
at com.test.TestService.sendMimeEmailWithThymeleaf(TestService.java:33) ~[classes/:na]
at com.test.MimeEmailWithThymeleafApplication.sendEmail(MimeEmailWithThymeleafApplication.java:39) [classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_66]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_66]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_66]
at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_66]
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:366) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:311) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:134) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
... 23 common frames omitted`

Tests with @DataJpaTest fail

Hello everybody,

First thing: amazing project, helped me a lot :D

I hope you can help me understading whats going on:

My POM:

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.6.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>it.ozimov</groupId>
            <artifactId>spring-boot-thymeleaf-email</artifactId>
            <version>0.6.3</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!--seems that spring boot-thymeleaf does not inlcude this dependency (WHY ? o.o)
                https://stackoverflow.com/questions/39355821/spring-boot-and-thymeleaf-neko-html-error
           -->
        <dependency>
            <groupId>net.sourceforge.nekohtml</groupId>
            <artifactId>nekohtml</artifactId>
        </dependency>
        //... other stuff

    </dependencies>

On my project i have a few tests (~50) annotated with @DataJpaTest.
after i have imported spring-boot-thymeleaf-email , only those tests are failing.

@DataJpaTest
public class TokenRepositoryTest extends BaseAbstractTest {

	@Test
	public void delete()
	{
		//STUFF
	}
}

With always same reason:

java.lang.IllegalStateException: Failed to load ApplicationContext

	at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
	at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83)
	at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:189)
	at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:131)
	at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:230)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:228)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:287)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:289)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:247)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
	at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
	at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'thymeleafTemplateService': Unsatisfied dependency expressed through field 'thymeleafEngine'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.thymeleaf.spring4.SpringTemplateEngine' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588)
	at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693)
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
	at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:120)
	at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98)
	at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116)
	... 24 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.thymeleaf.spring4.SpringTemplateEngine' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1493)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1104)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
	... 42 more

but if i replace @DataJpaTest with @SpringBootTest (like any other tests) everything seems to be ok, the SpringTemplateEngine bean get loaded.

I can't understand why during startup is looking for autowire thymeleafTemplateService bean, i'm not expecting that, i'm expecting getting loaded only those autoconfiguration listed here:
http://docs.spring.io/spring-boot/docs/current/reference/html/test-auto-configuration.html

am i missing something ? if so, what ?

Not working well with Unit Test and Thymeleaf

Hi,

I'm using the following in my spring-boot project.

spring-boot-starter-parent: 2.0.0.RELEASE
spring-boot-starter-thymeleaf
spring-boot-thymeleaf-email: 0.6.3

I am able to use this email-tool to work with thymeleaf for sending of email, but unable to get it working when I'm running on Unit Test.

I have a AccountControllerTest with a @MockBean of MailService. After I ran the unit test, it gives me the following exception.

java.lang.IllegalStateException: Failed to introspect Class [it.ozimov.springboot.mail.templating.service.ThymeleafTemplateService] from ClassLoader [sun.misc.Launcher$AppClassLoader@22d8cfe0]
at org.springframework.util.ReflectionUtils.getDeclaredFields(ReflectionUtils.java:759) ~[spring-core-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.util.ReflectionUtils.doWithFields(ReflectionUtils.java:724) ~[spring-core-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.util.ReflectionUtils.doWithFields(ReflectionUtils.java:709) ~[spring-core-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.boot.test.mock.mockito.DefinitionsParser.parse(DefinitionsParser.java:62) ~[spring-boot-test-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at org.springframework.boot.test.mock.mockito.MockitoPostProcessor.postProcessBeanFactory(MockitoPostProcessor.java:139) ~[spring-boot-test-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at org.springframework.boot.test.mock.mockito.MockitoPostProcessor.postProcessBeanFactory(MockitoPostProcessor.java:131) ~[spring-boot-test-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:284) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:172) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:693) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:531) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752) ~[spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:388) ~[spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:327) ~[spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:138) [spring-boot-test-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99) [spring-test-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:117) [spring-test-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:107) [spring-test-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.postProcessFields(MockitoTestExecutionListener.java:99) [spring-boot-test-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.injectFields(MockitoTestExecutionListener.java:79) [spring-boot-test-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.prepareTestInstance(MockitoTestExecutionListener.java:54) [spring-boot-test-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:242) [spring-test-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:227) [spring-test-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289) [spring-test-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) [junit-4.12.jar:4.12]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291) [spring-test-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:246) [spring-test-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97) [spring-test-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) [junit-4.12.jar:4.12]
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) [junit-4.12.jar:4.12]
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) [junit-4.12.jar:4.12]
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) [junit-4.12.jar:4.12]
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) [junit-4.12.jar:4.12]
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) [spring-test-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) [spring-test-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.junit.runners.ParentRunner.run(ParentRunner.java:363) [junit-4.12.jar:4.12]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190) [spring-test-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) [.cp/:na]
Caused by: java.lang.NoClassDefFoundError: Lorg/thymeleaf/spring4/SpringTemplateEngine;
at java.lang.Class.getDeclaredFields0(Native Method) ~[na:1.8.0_161]
at java.lang.Class.privateGetDeclaredFields(Unknown Source) ~[na:1.8.0_161]
at java.lang.Class.getDeclaredFields(Unknown Source) ~[na:1.8.0_161]
at org.springframework.util.ReflectionUtils.getDeclaredFields(ReflectionUtils.java:754) ~[spring-core-5.0.4.RELEASE.jar:5.0.4.RELEASE]
... 41 common frames omitted
Caused by: java.lang.ClassNotFoundException: org.thymeleaf.spring4.SpringTemplateEngine
at java.net.URLClassLoader.findClass(Unknown Source) ~[na:1.8.0_161]
at java.lang.ClassLoader.loadClass(Unknown Source) ~[na:1.8.0_161]
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) ~[na:1.8.0_161]
at java.lang.ClassLoader.loadClass(Unknown Source) ~[na:1.8.0_161]
... 45 common frames omitted

2018-03-18 03:07:06.844 INFO 2056 --- [ main] o.s.w.c.s.GenericWebApplicationContext : Closing org.springframework.web.context.support.GenericWebApplicationContext@267517e4: startup date [Sun Mar 18 03:07:06 SGT 2018]; root of context hierarchy
2018-03-18 03:07:06.844 ERROR 2056 --- [ main] o.s.test.context.TestContextManager : Caught exception while allowing TestExecutionListener [org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener@68e5eea7] to prepare test instance [com.sample.account.AccountControllerTest@62ce72ff]

java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:125) ~[spring-test-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:107) ~[spring-test-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.postProcessFields(MockitoTestExecutionListener.java:99) ~[spring-boot-test-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.injectFields(MockitoTestExecutionListener.java:79) ~[spring-boot-test-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.prepareTestInstance(MockitoTestExecutionListener.java:54) ~[spring-boot-test-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:242) ~[spring-test-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:227) [spring-test-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289) [spring-test-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) [junit-4.12.jar:4.12]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291) [spring-test-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:246) [spring-test-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97) [spring-test-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) [junit-4.12.jar:4.12]
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) [junit-4.12.jar:4.12]
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) [junit-4.12.jar:4.12]
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) [junit-4.12.jar:4.12]
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) [junit-4.12.jar:4.12]
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) [spring-test-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) [spring-test-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.junit.runners.ParentRunner.run(ParentRunner.java:363) [junit-4.12.jar:4.12]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190) [spring-test-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) [.cp/:na]
Caused by: java.lang.IllegalStateException: Failed to introspect Class [it.ozimov.springboot.mail.templating.service.ThymeleafTemplateService] from ClassLoader [sun.misc.Launcher$AppClassLoader@22d8cfe0]
at org.springframework.util.ReflectionUtils.getDeclaredFields(ReflectionUtils.java:759) ~[spring-core-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.util.ReflectionUtils.doWithFields(ReflectionUtils.java:724) ~[spring-core-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.util.ReflectionUtils.doWithFields(ReflectionUtils.java:709) ~[spring-core-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.boot.test.mock.mockito.DefinitionsParser.parse(DefinitionsParser.java:62) ~[spring-boot-test-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at org.springframework.boot.test.mock.mockito.MockitoPostProcessor.postProcessBeanFactory(MockitoPostProcessor.java:139) ~[spring-boot-test-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at org.springframework.boot.test.mock.mockito.MockitoPostProcessor.postProcessBeanFactory(MockitoPostProcessor.java:131) ~[spring-boot-test-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:284) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:172) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:693) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:531) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752) ~[spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:388) ~[spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:327) ~[spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:138) ~[spring-boot-test-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99) ~[spring-test-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:117) ~[spring-test-5.0.4.RELEASE.jar:5.0.4.RELEASE]
... 26 common frames omitted
Caused by: java.lang.NoClassDefFoundError: Lorg/thymeleaf/spring4/SpringTemplateEngine;
at java.lang.Class.getDeclaredFields0(Native Method) ~[na:1.8.0_161]
at java.lang.Class.privateGetDeclaredFields(Unknown Source) ~[na:1.8.0_161]
at java.lang.Class.getDeclaredFields(Unknown Source) ~[na:1.8.0_161]
at org.springframework.util.ReflectionUtils.getDeclaredFields(ReflectionUtils.java:754) ~[spring-core-5.0.4.RELEASE.jar:5.0.4.RELEASE]
... 41 common frames omitted
Caused by: java.lang.ClassNotFoundException: org.thymeleaf.spring4.SpringTemplateEngine
at java.net.URLClassLoader.findClass(Unknown Source) ~[na:1.8.0_161]
at java.lang.ClassLoader.loadClass(Unknown Source) ~[na:1.8.0_161]
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) ~[na:1.8.0_161]
at java.lang.ClassLoader.loadClass(Unknown Source) ~[na:1.8.0_161]
... 45 common frames omitted

Please help. Let me know what other information is required. I'll provide them.

Thank you!

Dynamic emails with templates is failing with exception

The dynamic emails with templates is failing with the exception :
java.lang.NullPointerException: body
at open.springboot.mail.model.impl.EmailImpl.(EmailImpl.java:42) ~[spring-boot-email-tools-0.1.1.jar:0.1.1]
at open.springboot.mail.model.impl.EmailImpl$EmailImplBuilder.build(EmailImpl.java:44) ~[spring-boot-email-tools-0.1.1.jar:0.1.1]
In open.springboot.mail.model.impl.EmailImpl, removing the @nonnull annotation of the body field fixes the problem.

Find below an extract of my code :

email = EmailImpl.builder().from(new InternetAddress("[email protected]", "SoulPay System"))
        .to(Lists.newArrayList(new InternetAddress(operation.getBeneficiary().getEmail(),
        operation.getOperator().getFullName())))
        .subject("Declaration").encoding(Charset.forName("UTF-8")).build();
modelObject.put(NotifParamsConstants.PARAM_INIT_PUBLIC_NAME, operation.getOperator().getFullName());
modelObject.put(NotifParamsConstants.PARAM_CREDITED_WALLET_DESC, creditedWallet.getAccName());
modelObject.put(NotifParamsConstants.PARAM_TRANSACTION_AMOUNT,customFormat.format(operation.getTotal()));
modelObject.put(NotifParamsConstants.PARAM_TRANSACTION_ID, operation.getReference());
modelObject.put(NotifParamsConstants.PARAM_BALANCE_AMOUNT, customFormat.format(creditedAccountBalance));
emailService.send(email, "DEC_BENEF_EMAIL.ftl", modelObject); 

Issue on deployment

Hey

Here Here is the stack trace , that I am getting while I am trying to use thymeleaf engine.

Can anybody help me on this ?


APPLICATION FAILED TO START


Description:

Field javaMailService in com.skc.core.communication.email.SampleEmailServiceImpl required a bean of type 'org.springframework.mail.javamail.JavaMailSender' that could not be found.
- Bean method 'mailSender' not loaded because AnyNestedCondition 0 matched 2 did not; NestedCondition on MailSenderAutoConfiguration.MailSenderCondition.JndiNameProperty @ConditionalOnProperty (spring.mail.jndi-name) did not find property 'jndi-name'; NestedCondition on MailSenderAutoConfiguration.MailSenderCondition.HostProperty @ConditionalOnProperty (spring.mail.host) did not find property 'host'

Action:

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

Thymeleaf template didn't work

I tried the Thymeleaf full template and copy-pasted your example , just replacing freemarker template with Thymeleaf, the template version didn't work. The error is :

java.lang.NoSuchMethodError: com.google.common.base.Preconditions.checkArgument(ZLjava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V
	at it.ozimov.springboot.mail.templating.service.ThymeleafTemplateService.mergeTemplateIntoString(ThymeleafTemplateService.java:55) ~[spring-boot-thymeleaf-email-0.6.3.jar:0.6.3]
	at it.ozimov.springboot.mail.service.defaultimpl.DefaultEmailService.send(DefaultEmailService.java:103) ~[spring-boot-email-core-0.6.3.jar:0.6.3]
	at com.eeposit.signal.service.impl.MailSenderService.lambda$0(MailSenderService.java:69) ~[classes/:na]
	at java.util.Spliterators$ArraySpliterator.forEachRemaining(Unknown Source) ~[na:1.8.0_77]
	at java.util.stream.ReferencePipeline$Head.forEach(Unknown Source) ~[na:1.8.0_77]
	at com.eeposit.signal.service.impl.MailSenderService.sendEmailWithTemplating(MailSenderService.java:51) ~[classes/:na]
	at com.eeposit.signal.controller.UserController.sendMail(UserController.java:58) ~[classes/:na]
	at com.eeposit.signal.controller.UserController$$FastClassBySpringCGLIB$$b240e6af.invoke(<generated>) ~[classes/:na]
	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-4.3.13.RELEASE.jar:4.3.13.RELEASE]
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738) ~[spring-aop-4.3.13.RELEASE.jar:4.3.13.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) ~[spring-aop-4.3.13.RELEASE.jar:4.3.13.RELEASE]
	at org.springframework.aop.aspectj.AspectJAfterAdvice.invoke(AspectJAfterAdvice.java:47) ~[spring-aop-4.3.13.RELEASE.jar:4.3.13.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.13.RELEASE.jar:4.3.13.RELEASE]
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) ~[spring-aop-4.3.13.RELEASE.jar:4.3.13.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.13.RELEASE.jar:4.3.13.RELEASE]
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673) ~[spring-aop-4.3.13.RELEASE.jar:4.3.13.RELEASE]
	at com.eeposit.signal.controller.UserController$$EnhancerBySpringCGLIB$$5454d811.sendMail(<generated>) ~[classes/:na]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_77]
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_77]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_77]
	at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_77]
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97) ~[spring-webmvc-4.3.13.RELEASE.jar:4.3.13.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) ~[spring-webmvc-4.3.13.RELEASE.jar:4.3.13.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) ~[spring-webmvc-4.3.13.RELEASE.jar:4.3.13.RELEASE]
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.3.13.RELEASE.jar:4.3.13.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967) ~[spring-webmvc-4.3.13.RELEASE.jar:4.3.13.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901) ~[spring-webmvc-4.3.13.RELEASE.jar:4.3.13.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) ~[spring-webmvc-4.3.13.RELEASE.jar:4.3.13.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) ~[spring-webmvc-4.3.13.RELEASE.jar:4.3.13.RELEASE]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:635) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) ~[spring-webmvc-4.3.13.RELEASE.jar:4.3.13.RELEASE]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.5.23.jar:8.5.23]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
	at org.springframework.web.servlet.resource.ResourceUrlEncodingFilter.doFilter(ResourceUrlEncodingFilter.java:59) ~[spring-webmvc-4.3.13.RELEASE.jar:4.3.13.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:317) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
	at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
	at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
	at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
	at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
	at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
	at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
	at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
	at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
	at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:100) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
	at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
	at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
	at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
	at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:347) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:263) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
	at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:108) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
	at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.23.jar:8.5.23]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478) [tomcat-embed-core-8.5.23.jar:8.5.23]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.23.jar:8.5.23]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) [tomcat-embed-core-8.5.23.jar:8.5.23]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.23.jar:8.5.23]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [tomcat-embed-core-8.5.23.jar:8.5.23]
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803) [tomcat-embed-core-8.5.23.jar:8.5.23]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.23.jar:8.5.23]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) [tomcat-embed-core-8.5.23.jar:8.5.23]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459) [tomcat-embed-core-8.5.23.jar:8.5.23]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.23.jar:8.5.23]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [na:1.8.0_77]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [na:1.8.0_77]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.23.jar:8.5.23]
	at java.lang.Thread.run(Unknown Source) [na:1.8.0_77]


Email log anonymizer

Allow the possibility to register an optional bean that should be used in logging to anonymize/format the email toString() value.
Maybe someone does not want to store private content in the logs or simply needs to save some disk space.

how to run sending-mime-email-with-thymeleaf-example project

my project structure

I use intellij idea debug run MimeEmailWithThymeleafApplication.java did not work

├── pom.xml
├── sending-mime-email-with-thymeleaf-example.iml
├── src
│   └── main
│   ├── java
│   │   └── com
│   │   └── test
│   │   ├── MimeEmailWithThymeleafApplication.java
│   │   └── TestService.java
│   └── resources
│   ├── application.yml
│   ├── attachments
│   │   └── Questo\ documento\ xxx\ un\ test.pdf
│   ├── images
│   │   └── galaxy.jpeg
│   └── templates
│   └── subfolder
│   └── emailTemplate.html
└── target
├── classes
│   ├── application.yml
│   ├── attachments
│   │   └── Questo\ documento\ xxx\ un\ test.pdf
│   ├── com
│   │   └── test
│   │   ├── MimeEmailWithThymeleafApplication$1.class
│   │   ├── MimeEmailWithThymeleafApplication.class
│   │   └── TestService.class
│   ├── images
│   │   └── galaxy.jpeg
│   └── templates
│   └── subfolder
│   └── emailTemplate.html
├── generated-sources
│   └── annotations
├── maven-archiver
│   └── pom.properties
├── maven-status
│   └── maven-compiler-plugin
│   └── compile
│   └── default-compile
│   ├── createdFiles.lst
│   └── inputFiles.lst
└── sending-mime-email-with-thymeleaf-example-0.6.3.jar

error:
`
Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2017-12-20 11:48:43.392 ERROR 96985 --- [ main] o.s.boot.SpringApplication : Application startup failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mimeEmailWithThymeleafApplication': Invocation of init method failed; nested exception is org.springframework.mail.MailSendException: Mail server connection failed; nested exception is javax.mail.MessagingException: Could not convert socket to TLS;
nested exception is:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target. Failed messages: javax.mail.MessagingException: Could not convert socket to TLS;
nested exception is:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target; message exceptions (1) are:
Failed message 1: javax.mail.MessagingException: Could not convert socket to TLS;
nested exception is:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:137) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:409) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1620) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867) ~[spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543) ~[spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at com.test.MimeEmailWithThymeleafApplication.main(MimeEmailWithThymeleafApplication.java:30) [classes/:na]
Caused by: org.springframework.mail.MailSendException: Mail server connection failed; nested exception is javax.mail.MessagingException: Could not convert socket to TLS;
nested exception is:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target. Failed messages: javax.mail.MessagingException: Could not convert socket to TLS;
nested exception is:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:432) ~[spring-context-support-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:345) ~[spring-context-support-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:340) ~[spring-context-support-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at it.ozimov.springboot.mail.service.defaultimpl.DefaultEmailService.send(DefaultEmailService.java:125) ~[spring-boot-email-core-0.5.0.jar:0.5.0]
at com.test.TestService.sendMimeEmailWithThymeleaf(TestService.java:54) ~[classes/:na]
at com.test.MimeEmailWithThymeleafApplication.sendEmail(MimeEmailWithThymeleafApplication.java:40) [classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_20]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_20]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_20]
at java.lang.reflect.Method.invoke(Method.java:483) ~[na:1.8.0_20]
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:366) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:311) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:134) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
... 18 common frames omitted
Caused by: javax.mail.MessagingException: Could not convert socket to TLS
at com.sun.mail.smtp.SMTPTransport.startTLS(SMTPTransport.java:2064) ~[javax.mail-1.5.6.jar:1.5.6]
at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:724) ~[javax.mail-1.5.6.jar:1.5.6]
at javax.mail.Service.connect(Service.java:366) ~[javax.mail-1.5.6.jar:1.5.6]
at org.springframework.mail.javamail.JavaMailSenderImpl.connectTransport(JavaMailSenderImpl.java:501) ~[spring-context-support-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:421) ~[spring-context-support-4.3.10.RELEASE.jar:4.3.10.RELEASE]
... 30 common frames omitted
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) ~[na:1.8.0_20]
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1917) ~[na:1.8.0_20]
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:301) ~[na:1.8.0_20]
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:295) ~[na:1.8.0_20]
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1369) ~[na:1.8.0_20]
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:156) ~[na:1.8.0_20]
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:925) ~[na:1.8.0_20]
at sun.security.ssl.Handshaker.process_record(Handshaker.java:860) ~[na:1.8.0_20]
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1043) ~[na:1.8.0_20]
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1343) ~[na:1.8.0_20]
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1371) ~[na:1.8.0_20]
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1355) ~[na:1.8.0_20]
at com.sun.mail.util.SocketFetcher.configureSSLSocket(SocketFetcher.java:598) ~[javax.mail-1.5.6.jar:1.5.6]
at com.sun.mail.util.SocketFetcher.startTLS(SocketFetcher.java:525) ~[javax.mail-1.5.6.jar:1.5.6]
at com.sun.mail.smtp.SMTPTransport.startTLS(SMTPTransport.java:2059) ~[javax.mail-1.5.6.jar:1.5.6]
... 34 common frames omitted
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:387) ~[na:1.8.0_20]
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292) ~[na:1.8.0_20]
at sun.security.validator.Validator.validate(Validator.java:260) ~[na:1.8.0_20]
at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324) ~[na:1.8.0_20]
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229) ~[na:1.8.0_20]
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124) ~[na:1.8.0_20]
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1351) ~[na:1.8.0_20]
... 44 common frames omitted
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:145) ~[na:1.8.0_20]
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:131) ~[na:1.8.0_20]
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280) ~[na:1.8.0_20]
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382) ~[na:1.8.0_20]
... 50 common frames omitted
`

When using boot maven without a parent

when i using boot maven without a parent, error:

java.lang.NoSuchMethodError: com.google.common.base.Preconditions.checkArgument(ZLjava/lang/String;Ljava/lang/Object;)V

at it.ozimov.springboot.mail.templating.service.FreemarkerTemplateService.mergeTemplateIntoString(FreemarkerTemplateService.java:50) ~[spring-boot-freemarker-email-0.6.3.jar:0.6.3]
at it.ozimov.springboot.mail.service.defaultimpl.DefaultEmailService.send(DefaultEmailService.java:103) ~[spring-boot-email-core-0.6.3.jar:0.6.3]
at com.ahies.service.message.email.controller.EmailController.sendEmail(EmailController.java:80) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_152]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_152]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_152]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_152]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133) ~[spring-web-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97) ~[spring-webmvc-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) ~[spring-webmvc-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) ~[spring-webmvc-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967) ~[spring-webmvc-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901) ~[spring-webmvc-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) ~[spring-webmvc-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) ~[spring-webmvc-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:635) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) ~[spring-webmvc-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.5.23.jar:8.5.23]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:108) ~[spring-web-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81) ~[spring-web-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) ~[spring-web-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.23.jar:8.5.23]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478) [tomcat-embed-core-8.5.23.jar:8.5.23]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.23.jar:8.5.23]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) [tomcat-embed-core-8.5.23.jar:8.5.23]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.23.jar:8.5.23]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [tomcat-embed-core-8.5.23.jar:8.5.23]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803) [tomcat-embed-core-8.5.23.jar:8.5.23]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.23.jar:8.5.23]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) [tomcat-embed-core-8.5.23.jar:8.5.23]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459) [tomcat-embed-core-8.5.23.jar:8.5.23]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.23.jar:8.5.23]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_152]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_152]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.23.jar:8.5.23]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_152]

If i change the parent with spring boot parent,it is ok !

org.springframework.boot
spring-boot-starter-parent
1.5.8.RELEASE

What happened?

How to make "send" call to be async

Hi

I am sending an email at the end of a registration process..
I want the call to "send" function to be asynchronous and not to wait for the function to come back before I can return from my own function ..

How shall I do it except "schedule it" for after 10 seconds ?

Thanks

Daniel

Application upgradation

Hi,

Is there any plan to upgrade spring boot to 2.0.1.RELEASE version ? If yes, when it will be available tentatively ?

Add template pre-evaluation

Currently the email with template are scheduled and compiled through the template engine when they need to be sent. However, this may affect the response time when thousands email need to be executed simultaneously.
Therefore, it could be a good idea to start compiling the templates in advance when the burden is lower.

Upgrade for Spring Boot 2.0

When trying to use the package with Spring Boot 2.0 I get the following exception:

Caused by: java.lang.IllegalStateException: Failed to introspect Class [it.ozimov.springboot.mail.templating.service.ThymeleafTemplateService] from ClassLoader [sun.misc.Launcher$AppClassLoader@18b4aac2]
	at org.springframework.util.ReflectionUtils.getDeclaredFields(ReflectionUtils.java:759) ~[spring-core-5.0.4.RELEASE.jar:5.0.4.RELEASE]
	at org.springframework.util.ReflectionUtils.doWithLocalFields(ReflectionUtils.java:691) ~[spring-core-5.0.4.RELEASE.jar:5.0.4.RELEASE]
	at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.buildPersistenceMetadata(PersistenceAnnotationBeanPostProcessor.java:410) ~[spring-orm-5.0.4.RELEASE.jar:5.0.4.RELEASE]
	at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findPersistenceMetadata(PersistenceAnnotationBeanPostProcessor.java:394) ~[spring-orm-5.0.4.RELEASE.jar:5.0.4.RELEASE]
	at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.postProcessMergedBeanDefinition(PersistenceAnnotationBeanPostProcessor.java:332) ~[spring-orm-5.0.4.RELEASE.jar:5.0.4.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyMergedBeanDefinitionPostProcessors(AbstractAutowireCapableBeanFactory.java:1016) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
	... 20 common frames omitted
Caused by: java.lang.NoClassDefFoundError: Lorg/thymeleaf/spring4/SpringTemplateEngine;
	at java.lang.Class.getDeclaredFields0(Native Method) ~[na:1.8.0_144]
	at java.lang.Class.privateGetDeclaredFields(Class.java:2583) ~[na:1.8.0_144]
	at java.lang.Class.getDeclaredFields(Class.java:1916) ~[na:1.8.0_144]
	at org.springframework.util.ReflectionUtils.getDeclaredFields(ReflectionUtils.java:754) ~[spring-core-5.0.4.RELEASE.jar:5.0.4.RELEASE]
	... 26 common frames omitted
Caused by: java.lang.ClassNotFoundException: org.thymeleaf.spring4.SpringTemplateEngine
	at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[na:1.8.0_144]
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_144]
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335) ~[na:1.8.0_144]
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_144]
	... 30 common frames omitted`

Seems like an issue with the reference to org.thymeleaf.spring4.SpringTemplateEngine since Spring Boot 2.0 uses Spring 5, specifically:

org.springframework.boot:spring-boot-starter-mail:2.0.0.RELEASE
org.springframework:spring-core:5.0.4.RELEASE
org.thymeleaf:thymeleaf:3.0.9.RELEASE

Cannot start application

Adding the tag @EnableEmailTools and properties:

spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=da*******[email protected]
spring.mail.password=******
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true

spring.mail.scheduler.persistence.enabled=false
spring.mail.scheduler.persistence.redis.embedded=false
spring.mail.scheduler.persistence.redis.enabled=false

Gives me this error when starting:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'emailRendererConfiguration' defined in URL [jar:file:/home/vincas/.gradle/caches/modules-2/files-2.1/it.ozimov/spring-boot-email-core/0.6.1/a7534f78a6e2217af3300702c975d1cee2d4165e/spring-boot-email-core-0.6.1.jar!/it/ozimov/springboot/mail/configuration/EmailRendererConfiguration.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [it.ozimov.springboot.mail.configuration.EmailRendererConfiguration$$EnhancerBySpringCGLIB$$ffe520f7]: No default constructor found; nested exception is java.lang.NoSuchMethodException: it.ozimov.springboot.mail.configuration.EmailRendererConfiguration$$EnhancerBySpringCGLIB$$ffe520f7.<init>()
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1105) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1050) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839) ~[spring-context-4.2.4.RELEASE.jar:4.2.4.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538) ~[spring-context-4.2.4.RELEASE.jar:4.2.4.RELEASE]
	at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118) ~[spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:766) [spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
	at org.springframework.boot.SpringApplication.createAndRefreshContext(SpringApplication.java:361) [spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) [spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1191) [spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1180) [spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
	at react.BootReactApplication.main(BootReactApplication.java:14) [main/:na]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_131]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_131]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_131]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_131]
	at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) [spring-boot-devtools-1.3.2.RELEASE.jar:1.3.2.RELEASE]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [it.ozimov.springboot.mail.configuration.EmailRendererConfiguration$$EnhancerBySpringCGLIB$$ffe520f7]: No default constructor found; nested exception is java.lang.NoSuchMethodException: it.ozimov.springboot.mail.configuration.EmailRendererConfiguration$$EnhancerBySpringCGLIB$$ffe520f7.<init>()
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:85) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1098) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
	... 22 common frames omitted
Caused by: java.lang.NoSuchMethodException: it.ozimov.springboot.mail.configuration.EmailRendererConfiguration$$EnhancerBySpringCGLIB$$ffe520f7.<init>()
	at java.lang.Class.getConstructor0(Class.java:3082) ~[na:1.8.0_131]
	at java.lang.Class.getDeclaredConstructor(Class.java:2178) ~[na:1.8.0_131]
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:80) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
	... 23 common frames omitted

Using version 0.6.1, tried downgrading to 0.6.0 but to no avail.

Unable to send links as attachment

Hi

We are not able to attach a hyper link into thymeleaf email templates. We are getting below exception.

Link base "send_link" cannot be context relative (/) or page relative unless you implement the org.thymeleaf.context.IWebContext interface (context is of class: org.thymeleaf.context.Context)

No qualifying bean of type [it.ozimov.springboot.templating.mail.service.EmailService]

Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: it.ozimov.springboot.templating.mail.service.EmailService com.getui.logful.web.actuate.check.LogfulApiCheckScheduledTasks.emailService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [it.ozimov.springboot.templating.mail.service.EmailService] 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.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement

Content-Type is set as text/plain, not html, when using Freemarker

I create an Email via DefaultEmail.builder() and send it via emailService.send with a Freemarker template (without attachments).
The problem is that the Content-Type is set to text/plain, not html:

MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="----=_Part_1_600820203.1498641103737"

------=_Part_1_600820203.1498641103737
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 7bit

<!doctype html>
<html>
	<body>

I can also see that the MimeMessage returned from emailService.send has only one part with objectMimeType set to text/plain; charset=UTF-8.

I tried to set customHeaders but it does not help.

EmailService not recognised in@Autowired

Hi

I added

@ComponentScan(basePackages = {"my package name", "it.ozimov.springbooot.mail",
        "it.ozimov.springbooot.templating.mail.service"})

in the application class but when I still want to use the EmailService is not capable to Autowired it.

Here is the stack trace :

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [it.ozimov.springboot.templating.mail.service.EmailService] 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)}

Thanks for any advice..

Daniel

Custom email headers

As described in this StackOverflow question, it would be nice to have the possibility to set a custom header for the emails. This should be relatively easy.

Fail to run Spring

After configuring "spring-boot-mustache-email" as per docs, spring boot fail to start crashing with this error:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'priorityQueueSchedulerService' defined in URL [jar:file:/Users/Fraccaman/.m2/repository/it/ozimov/spring-boot-email-core/0.4.0/spring-boot-email-core-0.4.0.jar!/it/ozimov/springboot/templating/mail/service/defaultimpl/PriorityQueueSchedulerService.class]: Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'schedulerProperties': Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: com.google.common.base.Preconditions.checkState(ZLjava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V

Spring boot version: 1.5.1 RELEASE

Gmail blocks outgoing mail from Java app

I am using SpringBoot 1.4.1.RELEASE and autowiring the EmailService fails due to some reason.

Description:

Field emailService required a bean of type 'it.ozimov.springboot.templating.mail.service.EmailService' that could not be found.

Thymeleaf data conversion/formatting doesn't work

Using 0.6.1 with Spring Boot 1.5.4, it looks like I couldn't use ${{variable}}, either it is ignored and the formatting doesn't get applied, or I got exception like this:

Caused by: org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [@javax.persistence.Column @org.springframework.format.annotation.DateTimeFormat java.time.LocalDate] to type [java.lang.String]

spring-boot-pebble-email for non-web Spring boot

Hi guys,

Sorry if I'm asking this question in the wrong place.
Is there any way to use this library with template engine without web environment enabled.

Disabling the web #spring.main.web-environment=false will keep on getting the following

Field pebbleViewResolver in it.ozimov.springboot.mail.templating.service.PebbleTemplateService required a bean of type 'com.mitchellbosecke.pebble.spring4.PebbleViewResolver' that could not be found.
    - Bean method 'pebbleViewResolver' not loaded because @ConditionalOnWebApplication (required) not a web application


Action:

Consider revisiting the conditions above or defining a bean of type 'com.mitchellbosecke.pebble.spring4.PebbleViewResolver' in your configuration.

Add @EnableEmailTools annotation

Most of spring boot libraries has @Enable...Configuration annotation which can simply import you own @Configuration class. So instead of

@ComponentScan(basePackages = {"com.myapplication", "it.ozimov.springboot"})

It can be like that (not tested!)

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import(EmailToolsConfiguration.class)
@interface EnableEmailTools  {}

@Configuration
@ComponentScan("it.ozimov.springboot")
public class EmailToolsConfiguration {}

It gives for you the following:

  1. Decouples client logic from it.ozimov.springboot, you can easyly move any components, only keep annotation in same package.
  2. Your spring boot library looks more in standart way (e.g. modern, cool, new!!! ;)). It is easy to type "EE" in IDE to see "EnableEmailTools" in auto complete then google library name and go to readme file.

Dynamic modification configuration

At present, our configuration depends on the auto configuration of spring boot. In the running, if I want to change the configuration of the mail. What should I do?

I know spring cloud config can do, but now we don't use.

Support JSON for using spring-boot-email-tools as services/microservices over REST

Is that able to support json like following:
Any guidelines for how to extend thymeleaf for the purpose? or it is already supported?
or just which library convert them back to java POJO assumed the type retaining well.

For example Template with json

Tu quoque, <em>${item.stock.stockLocation}</em>!

        String json = "{\"price\": 22, \"name\":  \"product name\",  \"stock\":  { \"stockLocation\":  \"location\"  }}";
        map = mapper.readValue(json, new TypeReference<Map<String, String>>(){});
        final Map<String, Object> modelObject = new HashMap<>();
        modelObject.put("item", map);

emailService.send(email, "idus_martii.ftl", modelObject);

Template path gets removed not only extension.

hi,

In ThymeleafTemplateService.java method mergeTemplateIntoString is returning thymeleafEngine.process(getNameWithoutExtension(trimmedTemplateReference), context)

This causes a template location "path/template" to given to the engine as "template". Because of this all email templates have to be in the root of the template dir, it would be nicer to accept templates with paths.

Maybe use removeExtension instead of the google getNameWithoutExtension which also removes the path.

Problem loading application without the need of REDIS

When the persistence and the scheduler are disabled :

spring.mail.scheduler.enabled=false
spring.mail.scheduler.priorityLevels=10
spring.mail.scheduler.persistence.enabled=false
spring.mail.scheduler.persistence.redis.enabled=false
spring.mail.scheduler.persistence.redis.embedded=false
spring.mail.scheduler.persistence.redis.host=localhost
spring.mail.scheduler.persistence.redis.port=6381

This error keeps coming :

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'enableRedisKeyspaceNotificationsInitializer' defined in class path resource [org/springframework/session/data/redis/config/annotation/web/http/RedisHttpSessionConfiguration.class]: Invocation of init method failed; nested exception is org.springframework.data.redis.RedisConnectionFailureException: Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
	...
Caused by: org.springframework.data.redis.RedisConnectionFailureException: Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
	...
Caused by: redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
	...
Caused by: redis.clients.jedis.exceptions.JedisConnectionException: java.net.ConnectException: Connexion refusée (Connection refused)
	...
Caused by: java.net.ConnectException: Connexion refusée (Connection refused)
	...

Can you provide a way in the documentation to avoid this ?
I don't need the persistence or scheduling layer and don't want to install a redis instance just to send some mails.

BeanCreationException - When using basic email.

Very similar to this issue: #7 and this one: #48.

The only difference being that I am using @EnableEmailTools:

@SpringBootApplication
@EnableEmailTools
public class AdeyTrackApplication implements ApplicationRunner {	
    public static void main(String[] args) {
        SpringApplication.run(AdeyTrackApplication.class, args);
    }
}

I want to send an email when someone goes to "/Search/EmailTest" so I do:

	@Autowired
	private EmailService emailService;
	
	@RequestMapping(value="/Search/EmailTest", method = RequestMethod.GET)
	public ModelAndView TestEmail() throws UnsupportedEncodingException {
		
		final Email email = DefaultEmail.builder()
		        .from(new InternetAddress("[email protected]", "jon doe"))
		        .to(Lists.newArrayList(new InternetAddress("[email protected]", "jane doe")))
		        .subject("Track email test")
		        .body("testing email")
		        .encoding("UTF-8").build();

		   emailService.send(email);
		
		return new ModelAndView("index");
	}

I can't seem to get here because the application doesn't even start up and I get the following exceptions: BeanCreationException and UnsatisfiedDependencyException.

Here is part of my build.gradle file:

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web")
    testCompile("org.springframework.boot:spring-boot-starter-test")
    compile("org.springframework.boot:spring-boot-starter-data-rest")
    compile('org.springframework.boot:spring-boot-starter-mail')
    

   compile("org.springframework.boot:spring-boot-starter-actuator")

    // JPA
    compile("org.springframework.boot:spring-boot-starter-data-jpa")
    runtime("mysql:mysql-connector-java")
    compile("org.hibernate:hibernate-validator")
    compile("com.h2database:h2")

    // JSP
    compile("org.apache.tomcat.embed:tomcat-embed-jasper:8.0.23")
    compile("javax.servlet:jstl:1.2")

    // Security
    compile("org.springframework.boot:spring-boot-starter-security")
    testCompile("org.springframework.security:spring-security-test:4.0.1.RELEASE")

    // junit
    testCompile("org.springframework.security:spring-security-test:4.0.1.RELEASE")
    compile 'org.springframework.security:spring-security-taglibs:4.0.1.RELEASE'
    testCompile("junit:junit:4.12")

    compile("org.webjars:handsontable:0.17.0")
    compile("org.webjars:jquery:2.0.3-1")
    compile("org.webjars:bootstrap:3.3.5")
    compile("com.google.code.gson:gson:1.7.2")
    
    
    compile("it.ozimov:spring-boot-email-core:0.6.2")
    
    compile group: 'javax.mail', name: 'mail', version: '1.4'
}

When I run the application, I get the following exception https://gist.github.com/redrails/8ef251d15d22ce560a22663375afa684
(Posted on gist as it's gigantic)

TL;DR exception:
No qualifying bean of type [it.ozimov.springboot.mail.service.TemplateService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency.

I cannot seem to get to the root of this problem.

Also worth mentioning that I saw this issue too: #9
And tried following the example using @Service instead of directly Autowiring EmailService but I'm still getting the same it.ozimov.springboot.mail.service.TemplateService exception.

Make spring-boot-email-tools fault-tollerant

Currently, scheduling emails in the future does not guarantee that a shutdown or a failure of the application will preserve the scheduled emails. Clearly this solution is not acceptable in production.

A possible solution would be to use Camel Queues. Anyway, most likely Redis is the best choice for this task. There will be a proof of concept in this branch.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.