I did a bunch of reasonably large applications with Grails 2 a long while back, and although most have now been upgraded to Grails 6 and all the new stuff I've done uses Grails 6 (although I will start using 7 very soon), I feel I've not taken nearly as much advantage as I might have done of the capabilities provided by the newer versions. One thing I've been looking at in the last couple of days, which I've never used before, is Traits.
In an application I'm working on at the moment, I'm moving away from using standard SMTP email (for which I generally use the Mail plugin) to using an email provider via an API. As email will need to be sent from various parts of the application and I don't want to repeat myself, I want to have an email component I can call from anywhere (as with the Mail plugin). I would naturally think of a service class for this, which could be used from controllers and other services, Quartz jobs, whatever. But what about a Trait for this instead? I could then even use it from a domain class method should I need to (not that I ever would, I think). To make sense the Trait would have to be able to use configuration from my application.groovy file. so I would want to implement GrailsApplicationAware in it. I then implement this trait in a service class, in which 'grailsApplication' is injected. But when I go to compile I get an error like this:
Task :compileGroovy startup failed: /root/src/borderbus/grails-app/controllers/borderbus/AdminController.groovy: 11: The return type of java.lang.Object getGrailsApplication() in borderbus.AdminController is incompatible with grails.core.GrailsApplication in grails.web.api.WebAttributes . At [11:1] @ line 11, column 1. class AdminController implements BrevoTrait { ^ 1 error
This presumably means there's a conflict between the getGrailsApplication() method from two different sources, the trait and the service. Am I doing this right? How can I get around this problem without overcomplicating things? And is a Trait a natural fit for this, or is there a better way? I presume I could create my own plugin but it's not something I've ever done before and I imagine it might be more cumbersome than is ideal.