Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 4066600
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 20, 20262026-05-20T16:08:54+00:00 2026-05-20T16:08:54+00:00

Grails uses mailService from Spring. That service is synchronous, which means if SMTP goes

  • 0

Grails uses mailService from Spring. That service is synchronous, which means if SMTP goes down temporarily, application functioning is affected badly (HTTP 500).

I want to decouple the application from SMTP server.

The plan is to save ready-to-be-sent emails into an outbound queue and send them by timer, with retries. For my own code, when I call mailService directly, it is rather trivial – make a wrapper service and call it instead. But some of the plugins that my application uses (e.g. EmailConfirmation plugin) use the same mailService, and still fail, effectively blocking sign-up process, for instance.

I wonder how can I replace/wrap the definition of mailService to make all code, my own and plugins, transparently use my own service?

I.e.

  • Plugin code injects mailService
  • But instead of Spring default mailService my own code is injected
  • When plugin sends a email the email object is saved to DB instead
  • On timer a job wakes up, gets next N emails and tries to send them

Any ideas how to approach this problem?

P.S. I know about AsynchronousMail plugin. Unfortunately, its service must be called explicitely, i.e. it is not a drop-in replacement for mailService.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-20T16:08:54+00:00Added an answer on May 20, 2026 at 4:08 pm

    OK, it wasn’t that hard, after all. Easy steps first:

    Step one: prepare database table to store pending email records:

    class PendingEmail {
        Date sentAt = new Date()
        String fileName
    
        static constraints = {
            sentAt nullable: false
            fileName nullable: false, blank:false
        }
    }
    

    Step two: create a periodic task to send the pending emails. Note mailSender injection – it is part of original Grails Mail Plugin, so the sending (and configuration of it!) is made via Mail Plugin:

    import javax.mail.internet.MimeMessage
    
    class BackgroundEmailSenderJob {
    
        def concurrent = false
        def mailSender
    
        static triggers = {
            simple startDelay:15000l, repeatInterval: 30000l, name: "Background Email Sender"
        }
    
        def execute(context){
            log.debug("sending pending emails via ${mailSender}")
    
            // 100 at a time only
            PendingEmail.list(max:100,sort:"sentAt",order:"asc").each { pe ->
    
                // FIXME: do in transaction
                try {
                    log.info("email ${pe.id} is to be sent")
    
                    // try to send
                    MimeMessage mm = mailSender.createMimeMessage(new FileInputStream(pe.fileName))
                    mailSender.send(mm)
    
                    // delete message
                    log.info("email ${pe.id} has been sent, deleting the record")
                    pe.delete(flush:true)
    
                    // delete file too
                    new File(pe.fileName).delete();
                } catch( Exception ex ) {
                    log.error(ex);
                }
            }
        }
    }
    

    Step three: create a drop-in replacement of mailService that could be used by any Grails code, including plugins. Note mmbf injection: this is mailMessageBuilderFactory from Mail Plugin. The service uses the factory to serialize the incoming Closure calls into a valid MIME message, and then save it to the file system:

    import java.io.File;
    
    import org.springframework.mail.MailMessage
    import org.springframework.mail.javamail.MimeMailMessage
    
    class MyMailService {
        def mmbf
    
        MailMessage sendMail(Closure callable) {
            log.info("sending mail using ${mmbf}")
    
            if (isDisabled()) {
                log.warn("No mail is going to be sent; mailing disabled")
                return
            } 
    
            def messageBuilder = mmbf.createBuilder(mailConfig)
            callable.delegate = messageBuilder
            callable.resolveStrategy = Closure.DELEGATE_FIRST
            callable.call()
            def m = messageBuilder.finishMessage()
    
            if( m instanceof MimeMailMessage ) {
                def fil = File.createTempFile("mail", ".mime")
                log.debug("writing content to ${fil.name}")
                m.mimeMessage.writeTo(new FileOutputStream(fil))
    
                def pe = new PendingEmail(fileName: fil.absolutePath)
                assert pe.save(flush:true)
                log.debug("message saved for sending later: id ${pe.id}")
            } else {
                throw new IllegalArgumentException("expected MIME")
            }
        }
    
        def getMailConfig() {
            org.codehaus.groovy.grails.commons.ConfigurationHolder.config.grails.mail
        }
    
        boolean isDisabled() {
            mailConfig.disabled
        }
    }
    

    Step four: replace Mail Plugin’s mailService with the modified version, injecting it with the factory. In grails-app/conf/spring/resources.groovy:

    beans = {
        mailService(MyMailService) {
            mmbf = ref("mailMessageBuilderFactory")
        }
    }
    

    Done!

    From now on, any plugin or Grails code that uses/injects mailService will get a reference to MyMailService. The service will take requests to send the email, but instead of sending it it will serialize it onto disk, saving a record into database. A periodic task will load a bunch of such records every 30s and try to send them using the original Mail Plugin services.

    I have tested it, and it seems to work OK. I need to do cleanup here and there, add transactional scope around sending, make parameters configurable and so on, but the skeleton is a workable code already.

    Hope that helps someone.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I am developing grails application which uses file searching.For that I wrote the following
I have an existing grails application that uses spring-security plugin for authentication. I would
I have a grails app that uses the Spring-Security-Core plugin, which integrates Spring Security
I have a grails application that uses spring-security-core and spring-security-ldap, with authentication against Active
I have inherited a Grails app, which uses the Acegi 0.5.3 plugin. The application
I have a grails app that uses functionality from a set of custom java
I am developing a Grails-application which uses several databases, others are read-only and 1
I am working on a grails application which uses Amazon's SimpleDB. I changed a
I have an application that uses the grails multi-tenant-core plug-in to host multiple versions
I have a grails(2.0.3) application that has a jar dependency on another project which

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.