Tuesday, July 26, 2016

Urlmappings break weirdly with Grails

Ever started your grails application up and recieved a vomit of stacktraces complaining about being unable to set the URLMappings Bean?


Error creating bean with name 'grailsUrlMappingsHolder'

This is generally the result of the url mappings failing to "compile". Check that all your paths start with a "/" slash and any closures are correctly closed.

Wednesday, June 8, 2016

Intellij and Grails 3 Command Failure

File this one under "doh, thats obvious" but I completely spaced out as to why my Intellij commands to generate new grails resources - like creating a new taglib

Would fail with an error like:

"C:\Program Files\Java\jdk1.8.0_45\bin\java" -XX:+TieredCompilation [...] \lib\grails-rt.jar" org.grails.cli.GrailsCli create-taglib <className> Error |
Command [create-taglib] error: Profile [org.grails.profiles:base:3.1.6] declares and invalid dependency on parent profile [org.grails.profiles:base:3.1.6] (Use --stacktrace to see the full trace)

The solution is to ensure the intellij SDK settings are set to the same level of grails SDK specific within your gradle file. I had upgraded to grails 3.1.6 within my build, but IntelliJ uses its own settings to define which grails binary to use for generating classes.

(Notice how Intellij still thinks my project is using 3.1.8 although I had downgraded to 3.1.6 - another curious feature that may crop up later)

Friday, April 15, 2016

Switching Environments in Grails 3 BootStrap

Over the iterations of grails, the best method to do this has changed. But if you want to execute grails code only within a specific environment in grails 3, you can use the static methods on the grails.util.Environment class.


switch (Environment.getCurrent()) {

    case Environment.DEVELOPMENT:
        20.times {
            //do some thing
    case Environment.PRODUCTION:
        2.times {
            //do some other thing

Wednesday, March 16, 2016

Gmail Oauth2 with Spring and JavaMail with Grails

Setting up Gmail Email Sending with Grails (2+, 3+) Service

Most Web applications will send some sort of email to users. Lost passwords, invitations to join. Its a good way to reach professional users. Not so great for young people (they never check them) but in order to send emails, you have to get the connection right. I didn';t build a particular groovy way, I used java code within a grails service to make a simple method available to controllers and other serivces:

interface EmailService {
    * Send a set of emails and collect the results     
    * @param addresses list of addresses to send to
    * @param subject subject of email    
    * @param text  body of email   
    * @return a list of message IDs returned from the sending service    
    def send(List<String> addresses, String subject, String text)

    * Setup any needed state from config files etc.     
    void initialize()

Most of the default grails java mail setup questions (I'm using spring mail with grails because its mostly already on the classpath) you will find involve turning off enhanced seucirty in your gmail account in order to get around the error message you will recieve on startup:

Authentication failed; nested exception is javax.mail.AuthenticationFailedException: 534-5.7.14 <https://accounts.google.com/signin/continue?sarp=1&scc=1&plt=AKgnsbvO
534-5.7.14 SC261Te39VZ5jtNBz2mvwNtIGtZLxYulCRb8D2u6rGTAg69U2-tQsPDzI1YPgWUbVo1ZQm
534-5.7.14 MlSxYEJHBzyTk-tQKy-6GN5HACShag4XcqNYlxbyWHYvMyMICSTPuwRFzM_Rn2kUOKLcoY
534-5.7.14 hcEmEC6i4DrvVh4h8KTTdK1VxgyDwD6QzfDxWgUa0vM7ZcLRfIURv1CThW4B0G5XvVgG3a
534-5.7.14 t-wJ_9P1uU8YoJK2c-QbrhZe2H9qo> Please log in via your web browser and
534-5.7.14 then try again.
534-5.7.14  Learn more at
534 5.7.14  https://support.google.com/mail/answer/78754 h24sm11972231ioi.17 - gsmtp

Someone just tried to sign in to your Google Account someone@gmailaddress.com from an app that doesn't meet modern security standards." - Oh great, here goes my day

This cryptic error results from using a setup like (in resources.groovy):

emailService(GmailEmailService) {

templateMessage(SimpleMailMessage) {

mailSender(JavaMailSenderImpl) {
                javaMailProperties = [
                        "mail.transport.protocol" : "smtp",
                        "mail.smtp.auth" : true,
                        "mail.smtp.starttls.enable" : "true",
                        "mail.smtp.quitwait" : true,
                        "mail.debug" : true

But what if you wanted to use enhanced security? Well available in the more recent versions of JavaMail is support of Oauth2.

To begin with though, you are going to need to follow the google guidelines here to recieve api credentials for your webserver. You should end up with a set of JSON credentials for your service account. :

  "type": "service_account",
  "project_id": "someid",
  "private_key_id": "SOMEID",
  "private_key": "YOURKEY",
  "client_email": "someemail",
  "client_id": "someid",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://accounts.google.com/o/oauth2/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "someurl"

There is a branch here. You can choose to give the service account Delegate domain-wide authority (which I have done) or leave it at user-interactive mode. Since I dont want to have to ask my own company user account for permissions (which makes sense for a back-end webservice making sending email from only one user), I chose  to upgrade the account to domain-wide, which can be done in the console.

Adding Domain Wide Delegation means no prompts, but using an additional secret file

We will need to use these credentials to create oauth tokens that can be sent with each senmail request. To create these tokens (oauthtoken) you can use the Google Java API. (at the time of writing, the latest central maven available was: 'com.google.api-client:google-api-client:1.21.0') . Google has a guide available - but essentially you will be using the builder to setup a trusted account.

GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream(authFile)).createScoped(Collections.singleton("https://www.googleapis.com/auth/gmail.send")) //for SMTP access only

Then email setup can be pretty easy. A lot of the boiler plate of creating a javax.mail.transport can be made easier by using some Java Code provided by Google itself.

If like us, you were using google apps accounts - there is additional information required. As you may get responses like:

DEBUG SMTP: SASL: no response
DEBUG SMTP: SASL authentication failed

Things to check:

* You have allowed the client id access to the same scope you are requesting (Google Scopes listing)
* You are creating your Google credential and access token with a user to impersonate:

GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream(authFile))                .createScoped(Collections.singleton("https://www.googleapis.com/auth/gmail.send"))
credential.serviceAccountUser = "someuser@yourdomain.com" //important

Final Thoughts

After going through all of this trouble, I ended up switching to using the google api client and the gmail api client for java, while still using JavaMail for convience (google has a great guide here)

By the way, I reccomend using scheduling with retries in order to make sure your customers recieve their emails. It can be really annoying when an app fails to send that crucial forgot password email - they will often leave and not come back.

Turns out doing it the right way is a bit more involved - but worth it. One day your email's wont stop randomly working when google finally axes support for the basic authentication.

Wednesday, February 17, 2016

Grails3 and Spring Security

ERROR org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/].[grailsDispatcherServlet] - Servlet.service() for servlet grailsDispatcherServlet threw exception
java.lang.IllegalStateException: There was a problem retrieving the current GrailsWebRequest. This usually indicates a filter ordering issue (the 'springSecurityFilterChain' filter-mapping element must be positioned after the 'grailsWebRequest' element when using @Secured annotations).

This issue was bugging me on a new grails3 and spring security web application. It turns out there are more than few active bugs on this issue. I filed my own:


After a week of noodling on the issue and trying various leads - the root cause seems to be spring security is delegating to the embedded tomcat error pages for routes only covered by static rule mappings (while your application is still using annotations). Instead, the plugin should correctly delegate to your mapped errors pages within the grails system. Included in the above post is my work around, which I will repeat here. This will cause all errors encountered within static routes to use the correct mappings.

You must setup an error controller:

class ErrorController {

    def error() {
        render view: 'error'    }

    def invalid() {
        render view: 'error'    }

    def denied() {
        render view: 'denied'    }

    def notFound() {
        render view: 'notFound'    }

And use this controller within your URL mappings:

"400"(controller: "error", action: "invalid")
"500"(controller: "error", action: "denied")
"403"(controller: "error", action: "denied")

"404"(controller: "error", action: "notFound")

And finally disable the spring-secuurity error page within application.groovy

grails.plugin.springsecurity.adh.errorPage = null

FlowJs Upload Reciever for Grails

I chose flow.js (https://github.com/flowjs/flow.js) for my client side file uploading due to its fault tollerance. I use using the ng-flow (https://github.com/flowjs/ng-flow/) angular library that builds an excellent set of directives around the framework. The one downside is the lack of documentation on what it takes to build a server side compliment to this. The particular beckend I am using is Grails3 based (although this would work for earlier versions of grails with little modification).

I built a service that can be plugged into multiple controllers to achieve the effect. While I wont publish the whole service, here is a skelleton that should be enough to get you started.

Tuesday, October 23, 2012

Simple Scripts for replacing html tags

I recently had to upgrade a tag library we were using. However the latest version had refactored out some of the tags into a separate tag library. I needed to do two things:

1) Add a reference to the new tag library on each page that had previously been using the base library
2) Change the tags using the old library to update to use the new prefix

#Add a new line (using a\ option) to the files containing reference to struts-jquery-tags

find . -type f \( -iname "*.tag" -or -iname "*.jsp" \) -print -exec sed -i '/struts-jquery-tags\"\s%>/ a\
<%@ taglib prefix=\"sjg\" uri=\"\/struts-jquery-grid-tags\" %>' {} \;

#Find and replace references to the old sj:grid to use the new :sjg:grid
find . -type f \( -iname "*.tag" -or -iname "*.jsp" \) -print -exec sed -i 's/sj:grid/sjg:grid/g' {} \;

#Finally strip out some redundant information from header tags
find . -type f \( -iname "*.tag" -or -iname "*.jsp" \) -print -exec sed -i 's/head\suseJqGridPlugin=\"true\"/head/g' {} \;