Posts Tagged ‘Grails’

Performance tuning for Grails app in a memory constrained environment

Sunday, April 20th, 2008

Feedlr has been running quite well for a while, until a couple weeks ago, the server started to choke a lot. And I realized I had to do something to improve the performance. Actually, until then I had barely paid any attention performance-wise - getting the app up and running was the goal. And then with the growth of the app it’s time to do some work for that.

The Problem

The symptom of the performance bottleneck was that from time to time Tomcat would take a long time to respond, resulting in timeouts at the browser clients. This is caused by heavy swapping - apparently the 512MB RAM shared by all the services on the VPS, including Apache (with worker mpm), php, MySQL, and Tomcat, is less than abundant. But before upgrading my VPS, I want to see how far I can go with the current specs.

Attempting to optimize the code

My first attempt was to review my code and try to identify any possible memory leaks and memory inefficient spots. After working with profiling tools (I used an evaluation version of JProfiler, which is very good), and several refractory efforts, there was no obvious improvement. It didn’t look like a memory leak. And the effort trying to squeeze more memory from the code didn’t seem to pay off.

Tuning the JVM

Then I began to focus on tuning the JVM. The sporadic heavy swapping hints at inefficient garbage collections. But why is GC taking so much resources? Using GCViewer, I can see that the throughput can be as low as around 70%. And full GC time constantly reaches several minutes. (SliceHost has sent me a dozen heavy swap usage report already)

After some searching and study, first thing I tried was to decrease the maximum heap size. Yes, decrease it. Previously, I was assigning 384MB to the heap. Because while Tomcat is not running, I have a little less than 440MB free physical memory. Leaving some buffer, 384MB seems a reasonable number. But the excessive swapping and very long full GC time indicates that part of the heap must be slipping into the virtual memory. And virtual memory is the biggest enemy of JVM garbage collection. So I decreased the heap size incrementally, arriving at 270MB. And the GC log shows that the time full GC takes has considerably dropped.

To further improve the situation, I tried different GC policies. First I tried the Concurrent Mark Sweep GC policy, which is supposed to work very well with multi-processor servers and is optimized for response time. Profiling with the CMS options on my local workstation shows good results. And since “cat /proc/cpuinfo” shows that my VPS is equipped with 4 CPU’s, I was expecting to see obvious improvements.

However, to my great disappointment, CMS totally strangled my VPS. Soon after Tomcat starts up, CPU usage became constantly high and the Grails app responds even slower! I’m not exactly sure why, but it looks like the number of CPU’s shown at your VPS doesn’t mean it has the comparable concurrent processing power.

Then I gave up the CMS policy and tried the other GC policy suitable for servers, the Parallel policy. This turned out to work quite well on the VPS, together with “-XX:+UseParallelOldGC” which is available since Java 5 update 6 and enhanced in Java 6 which I’m running my app on.

The Results

I experimented with a few other JVM options, and finally achieved a throughput of above 98%. Full GC now usually takes around 1 second, occasionally maxing at over 10 seconds. I think there are some hard limitations to the server, but the results are already good enough for now. Here are the current ones which have achieved reasonable performance for my Grails app. These may not be the perfect setup since I haven’t tried the combinations exhaustively.

-server -Xmx270m -Xms270m -XX:MaxPermSize=80m -Xverify:none -XX:+UseParallelGC -XX:+UseParallelOldGC -XX:+UseAdaptiveSizePolicy -XX:SurvivorRatio=4 -XX:TargetSurvivorRatio=90 -XX:MaxTenuringThreshold=31 -XX:+AggressiveOpts

References

Below are some useful articles I’ve come across while tuning the JVM.

Further thoughts

I really love Grails for what it is: remarkably agile development with real joy. But as the person running the app, I have to deal with various issues of the stack that Grails sits on, which sometimes frustrates me.
On one hand this robust stack really grants Grails an advantage in the enterprise market. But on the other hand, this is no good news for the creators of hundreds and thousands of small web apps, pet projects, interesting weekend hacks and alike. The most obvious obstacle is Java hosting. It’s 2008 already, and there are still simply _no_ easily affordable and good enough hosting services for the Java stack! The entry cost is too high. With innovative services like Heroku and Googel App Engine emerging, the gap is even increasing. The barrier to actually making something useful on the web is being dramatically lowered. But yet, the Java stack is left out in the cold.

While this is a problem, it’s also an incredible opportunity. With Grails emerging, the Java stereotype can be changed. People can build agile web apps on top of the proven stack, which is the core competency of Grails as I see it. I want to build things with Grails. But I don’t want to worry about how to host my app. Now, who’s gonna give us the ultimate service to grow little ideas into reality?

How to create an interactive Twitter bot with Grails in 10 minutes

Tuesday, March 18th, 2008

A while ago I read this interesting post from Glen Smith about connecting to Google Talk with Grails. And I thought, “Wow, that’s really easy!” With merely a dozen lines of code you can already send messages via XMPP to Google Talk clients! And the other day I stumbled upon the Timer bot on Twitter. I thought, with Grails I really can do that in 10 minutes! So here it is, and you can do it in 10 minutes as well!

The way a twitter bot works

If you are already a Twitter geek, you can well skip to the next part. But if not, let’s first understand how an interactive bot on Twitter like the timer bot works.

Timer is a bot that can remind you with your message in a pre-defined amount of time. e.g. You send a direct message over Twitter to Timer like “d timer 45 call mom”, and it will send you a direct message back 45 minutes later, telling you “call mom”.

There are actually two ways to interact with Twitter.

  1. Using the REST API
  2. Talking to the Twitter IM bot directly over one of the supported IM networks.

We are talking about “interactive” bots here, which means that you can send some commands to it, and it reacts to your command. So we need to use the second approach. And since one can connect to Google Talk using the open XMPP protocol, talking to Twitter over Google Talk is apparently the better choice.

And here are the steps for some paperwork.

  1. Register a new user on Twitter to act as the bot account. Let’s name it “mytimer”.
  2. Log on as “mytimer”, and in the settings, add the Google Talk account which you are going to use for the bot to connect to Google Talk and “chat” with the Twitter IM bot. You need to log on to GTalk using this account and send the supplied verification code to the Twitter IM bot and get your GTalk account confirmed.

OK. Now we have our GTalk account bound to the Twitter bot account. We are going to write the code to make the bot alive.

The plan

Here’s how we are gonna do it.

  1. Connect to Google Talk service using the Smack XMPP library
  2. Listen to direct messages coming from the Twitter GTalk account twitter@twitter.com.
  3. When a direct message comes in, parse it and send the message back in the pre-defined amount of time.

A Twitter direct message sent over Google Talk looks like this:

Direct from {Sender_User_Name}:
{Message Body}

Reply with ‘d {Sender_User_Name} hi.’

A Twitter user name can only consist of letters, numbers, and “_”. So we can safely tokenize the message using spaces and newlines as separators. Also, the first and last line of the message are of the fixed format.

Our timer command spec is, described in regular expression:

^\d+(s|m|h)*\s.*$

e.g. 5m buy the milk

This command means to remind in 5 minutes with the reminder “buy the milk”. Accordingly, appended after the first number, “s” means seconds and “h” means hours.

The code monkey job

Now let’s see the code. First define the service settings in Config.groovy.

//File: Config.groovy
chat {
    serviceName = "gmail.com"
    host = "talk.google.com"
    port = 5222
    username = "bot@your.domain" //This is the Google Talk account you prepare for the bot
    password = "your_password" //The Google Talk password
}

Then create a service to hold the code, say, TwitBotService. It looks like this.

//File: TwitBotService.groovy
import org.codehaus.groovy.grails.commons.ConfigurationHolder as C
import org.jivesoftware.smack.Chat
import org.jivesoftware.smack.ConnectionConfiguration
import org.jivesoftware.smack.Roster
import org.jivesoftware.smack.XMPPConnection
import org.jivesoftware.smack.packet.Message
import org.jivesoftware.smack.PacketListener
import org.jivesoftware.smack.filter.PacketFilter
import org.jivesoftware.smack.filter.PacketTypeFilter
import org.jivesoftware.smack.packet.Message
import org.jivesoftware.smack.packet.Packet
import org.jivesoftware.smack.PacketListenerclass

TwitBotService {
    boolean transactional = false
    XMPPConnection connection

    def connect() {
        ConnectionConfiguration cc = new ConnectionConfiguration(
        C.config.chat.host,
        C.config.chat.port,
        C.config.chat.serviceName)
        connection = new XMPPConnection(cc)
        PacketFilter msgFilter = new PacketTypeFilter(Message.class)

        def myListener = [processPacket:{ packet ->
            log.debug "Received message from ${packet.from}, subject: ${packet.subject}, body: ${packet.body}"
            def msg = packet.body
            if(!msg) return
            def words = msg.tokenize(' \n')
            //Direct message body
            def body = words[3..-6]
            //The Twitter user who sent the command, and we are going to reply to
            def to = words[2][0..-2]
            //The amount of time delay
            def delay = words[3]
            switch(delay[-1]){
                case 's':
 	       log.debug "Delay in seconds"
 	       delay = delay[0..-2].toInteger()
 	       break
               case 'm':
 	       log.debug "Delay in minutes"
 	       delay = delay[0..-2].toInteger()*60
 	       break
 	  case 'h':
 	       log.debug "Delay in hours"
 	       delay = delay[0..-2].toInteger()*3600
 	       break
 	  default:
 	       //default unit is minute
 	       delay = delay.toInteger()*60
            }
            //The reminder text to send back
            def reminder = body[1..-1].join(' ')
            if(delay instanceof Integer){
                new Timer().runAfter(delay*1000){
 	       //Send back direct message 'd user message'
 	       def cmd = 'd ' << to << ' ' << reminder
 	       sendChat(packet.from, cmd.toString())
 	   }
            }
       }] as PacketListener
       try {
            log.debug "Connecting to server..."
            connection.connect()
            connection.login(C.config.chat.username,C.config.chat.password)
            connection.addPacketListener(myListener, msgFilter)
            log.debug "Connected to server"
       } catch (Exception e){
        	log.error "Connection failed: $e.message"
       }
    }

    def disconnect(){
        connection.disconnect()
    }

    def sendChat(String to, String msg) {
        try{
            Chat chat = connection.chatManager.createChat(to, null)
            def msgObj = new Message(to, Message.Type.chat)
            msgObj.body = msg
            chat.sendMessage(msgObj)
        } catch (Exception e) {
            log.error "Failed to send message"
        }
    }
}

And finally, to start the bot with your grails app, simply add a call to TwitBotService#connect() in BootStrap.groovy.

//File:BootStrap.groovy
    def gTalkService
    def init = { servletContext ->
        gTalkService.connect()
    }
    def destroy = {
        gTalkService.disconnect()
    }

So here it is, your own timer bot recreated (with a bit more features) in 10 minutes, quick and dirty. And with the same approach, you can create all sorts of interactive Twitter bots.

P.S. Why would you create a Twitter bot while you can create a Google Talk bot in the same way?

Well, a GTalk bot can only interact with online GTalk users. But by leveraging the Twitter platform, users can interact with your bot either online with GTalk, or offline with mobile SMS. And that all comes with no cost at all. Ain’t that cool?

Deploying Grails - Things I learned from Feedlr

Monday, March 10th, 2008

When I was about to deploy Feedlr on my VPS server there wasn’t much information about the deployment of Grails out there. I know that deploying a Grails war is just like a Java war. But are there going to be any differences? How much memory do I need? Will it eat any more hardware than a plain old Java app? I really have no idea. So this post is about the server stuff I’ve learned by doing the deployment for Feedlr.

I started by deploying my Grails app on Tomcat 6 on a 256M RAM VPS. And since my blogs are also hosted on this VPS, I use mod_proxy_ajp to connect Tomcat to Apache for Feedlr.

My first attempt on the 256 VPS turned out very badly. When I started Tomcat with Feedlr deployed, the server simply becomes very unresponsive and swap activity started flying. That’s a bad sign for “low memory”, I think. So I upgraded the server to 512M RAM and things began to look normal.

Then comes the optimization part. I really don’t have much server tuning experience, especially with a limited resource VPS. So all this is new and interesting to me, solving issues one by one.

The first bad thing happened was that whenever Tomcat ran for a while, like a couple hours, the whole VPS box began to eat a low of swap, and connection will often timeout. I suspected Tomcat, but it turned out to be Apache. The default installation on Ubuntu for Apache + PHP5 uses the Apache mpm_prefork module. The problem is that mpm_prefork spawns multiple Apache instances to handle requests to the server. And the default config is like

<IfModule mpm_prefork_module>
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxClients 150
MaxRequestsPerChild 0
</IfModule>

The default config worked fine when I was only hosting a couple blogs on the 256 box. But with a Grails app on Tomcat running, memory becomes critical. So then I changed the settings to smaller numbers and it has been working fine now.

<IfModule mpm_prefork_module>
StartServers 2
MinSpareServers 2
MaxSpareServers 4
MaxClients 150
MaxRequestsPerChild 0
</IfModule>

I will replace mpm_prefork with mpm_worker module since the latter is more efficient for concurrency. Aptitude on Ubuntu can’t figure out for you how to put mpm_worker and PHP5 together so there are some config work to do. Currently I’m running mpm_worker on my development/staging server and it’s working fine but I just don’t know how it’s gonna behave on a low memory environment. BTW. If you have anything to say about this I’m all ears.

Then it’s about Tomcat. Actually Tomcat is working great with Grails out of the box. The tuning is all about memory and efficiency. Here’s my Tomcat startup opts:

CATALINA_OPTS=”-server -Xmx420m -Xms420m -XX:MaxPermSize=128m -Dcom.sun.management.jmxremote”

I set the heap size to 420M since I want to leave some room for my blogs. And so far this setting has worked fine for me. The “-Dcom.sun.management.jmxremote” part is for LambdaProbe which I’m using as the server management app.

Besides, for the production environment, it’s better to set reloadable=”false” for the Tomcat Context of the app. It should be false by default. In this way new code won’t be reloaded on the fly, but it saves quite some server overhead which can be notable on a low memory environment.

And finally, server logging. Here’s my logging settings in Config.groovy. Log files will be saved daily for stdout and stacktrace.

log4j {
    appender.stdout = "org.apache.log4j.ConsoleAppender"
    appender.'stdout.layout'="org.apache.log4j.PatternLayout"
    appender.'stdout.layout.ConversionPattern'='[%r] %c{2} %m%n'

//    	rolling file logger
    appender.logfile = "org.apache.log4j.DailyRollingFileAppender"
    appender.'logfile.File' = "/path/to/public_html/feedlr.com/logs/feedlr_grails.log"
    appender.'logfile.layout' = "org.apache.log4j.PatternLayout"
    appender.'logfile.layout.ConversionPattern' = '%d{[ dd.MM.yy HH:mm:ss.SSS]} [%t] %-5p %c %x - %m%n'

    appender.errors = "org.apache.log4j.DailyRollingFileAppender"
    appender.'errors.layout'="org.apache.log4j.PatternLayout"
    appender.'errors.layout.ConversionPattern'='%d{[ dd.MM.yy HH:mm:ss.SSS]} [%t] %-5p %c %x - %m%n'
    appender.'errors.File'="/path/to/public_html/feedlr.com/logs/feedlr_grails_stacktrace.log" //prod setting
    rootLogger="error,stdout"
    logger {
        grails="info,stdout,logfile" //prod settings
        StackTrace="error,errors"
        org {
            codehaus.groovy.grails.web.servlet="info,stdout,logfile"  //  controllers
            codehaus.groovy.grails.web.pages="info,stdout,logfile" //  GSP
            codehaus.groovy.grails.web.sitemesh="info,stdout,logfile" //  layouts
            codehaus.groovy.grails."web.mapping.filter"="info,stdout,logfile" // URL mapping
            codehaus.groovy.grails."web.mapping"="info,stdout,logfile" // URL mapping
            codehaus.groovy.grails.commons="info,stdout,logfile" // core / classloading
            codehaus.groovy.grails.plugins="info,stdout,logfile" // plugins
            codehaus.groovy.grails.orm.hibernate="info,stdout,logfile" // hibernate integration
            springframework="off,stdout,logfile"
            hibernate="off,stdout,logfile"
        }
    }
    additivity.StackTrace=false
}

P.S. I’m using SliceHost’s VPS and it’s great. I especially love the on-demand slice resizing which will automatically resize your VPS in minutes, with data completely intact. So you can totally start with a frugal setup and grow as needed. And did I mention completely full control over your server? I won’t say more but I know your inner geek would love it once you use it. So if you are seeking some good server space for your project why not give it a try with my referral link :)

Feedlr is now alive!

Saturday, March 1st, 2008

Hi friend, my latest pet project feedlr has gone alive! After testing the initial version with friends, I’ve decided to make Feedlr open to the public now.

Feedlr is a service inspired by twitterfeed, built with Grails. It is both an automatic feed tweeting service like twitterfeed, and a bot showcase for miniblog users to browse, find, and follow interesting bots on popular miniblog services. Currently, Feedlr supports miniblogs including Twitter, JiWai, and FanFou. The idea is to make Feedlr a thriving farm of miniblog bots where anyone can create or adopt cute bots.

You can use Feedlr to broadcast feeds to multiple miniblogs

To do this, please first sign in or sign up for an account, and then click the “New” tab on the top and follow the simple wizard.

The wizard will ask for “bot accounts”, which means miniblog accounts used to broadcast the feeds. You should have already registered an account on a supported miniblog and provide the account information to the wizard.

A note on privacy here. Since the way miniblog API’s are designed, Feedlr has to have your bot login information in order to do the posting. So it’s strongly recommended that bot creators don’t use their personal accounts as bot accounts, but create dedicated accounts for the bot service only.

Feed creators can choose to attach a feed up to 2 bots at a time, choosing among the 3 currently supported services.

Feedlr is also a bot showcase

In addition, you can simply browse for bots on Feedlr and find interesting ones to follow. Once you want to follow a certain bot, there are two ways to follow it and both should take less than 10 seconds.

First, you can simply click the bot avatar and visit the bot’s homepage on the miniblog. Then just follow the bot as how you do it with the miniblog service.

Second, you can click the “Follow” hover menu. You will be prompted to enter your own login for the miniblog service where the bot is hosted. To ensure privacy and security, Feedlr does not record you login in any way. It’s strictly used to follow the bot for this one time.

Feedlr loves feeds, miniblogs, and you!

So start by feeding it with more feeds:)

If you have any comments, find any bugs, want any new features, or just want to say something, please leave a word or two by replying to this blog post. Feedlr is a new born baby. Love and caring makes it grow healthily and fast!

Streamlining JSON processing with Prototype 1.6

Saturday, February 9th, 2008

The other day I was doing some refactoring. I became aware that with Prototype 1.6, there comes a nice Ajax.Response object as the first argument of all Ajax callbacks. And as the documentation points out, the “responseJSON” property is “The JSON body of the response if the content-type of the request is set to application/json. null otherwise.”

I used to process the JSON responses from Grails the old way using the “response.responseText.evalJSON()” thing. So it looks like this process is nicely streamlined now. And now that I’ve replaced the stock prototype in Grails with the new 1.6 version, this is a low hanging fruit to make the code nicer. So why not?

In your Grails controller code, simply replace all occurrences of

render(contentType:"text/json", ...

With

render(contentType:"application/json", ...

And in your javascript, replace all

response.responseText.evalJSON()

with

response.responseJSON

Congratulations! Your code has just become one step more concise and prettier.

So here’s just a little tip I feel like sharing with you.

P.S. Grails 1.0 has been out a couple days now. Great news for all!

Undocumented goodies of Grails - Part 1

Tuesday, January 29th, 2008

Working with Grails you can often discover exciting features from time to time. And even better (or worse?), some of them are undocumented, which feels kind of like treasure hunting.

Lately I discovered this gem of feature which is left out of the latest documentation. You can use a closure with the <g:select> tag to fully customize the displayed values of your options list!

It works like this. For example you have a list of values indicating minutes, e.g. 15, 30, 60, 120, … You want to give the list to <g:select>, but you don’t want to simply display the bunch of numbers as-is because that’s ugly. You want the minute values to be displayed as “15 Minutes”, “30 Minutes”, “1 Hour”, “2 Hours”, etc.

How would you do this? Custom tag lib? It sure works, but definitely will cost you more than a one-liner. But using a closure to supply the formatting logics directly to <g:select>, this IS a one-liner!

<g:select from='${minutesList}' optionValue='${{it<60?("$it Minutes"):(it>60?("${it/60} Hours"):("${it/60} Hour"))}}' name='prettyList'/>

That’s it! The closure supplied to optionValue takes the List given by the “from” attribute, and iterates the List. Now your controller can take the raw minutes values while the front end displays human friendly minutes and hours reading.

By reading the <g:select> source code, you will see that the attribute “optionKey” can take a closure, too. What clever use of this can you think of now?

Update: I think part of the reason this is undocumented could be that this would encourage bad habits of littering the views with too much logic. So use it wisely. I recommend only using this for simple and clear one-liners.

Mini guide to rendering JSON with Grails

Sunday, January 13th, 2008

Grails has built-in support for a JSON building DSL, which, together with the render controller dynamic method, makes rendering JSON responses an enjoyable job. But there seems to be a lack of consolidated information in the official documentation to clarify all the bits about getting anything you want in JSON. So here’s my little mini guide to share with you.

Ground Rules

As the JSON spec reads,

JSON is built on two structures:

  • A collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.
  • An ordered list of values. In most languages, this is realized as an array, vector, list, or sequence.

So there are only two rules for rendering JSON with Grails.

1. To render a collection of name/value pairs (an object), use the method call syntax.

e.g.

render(contentType:'text/json'){
	pair(name:'value')
}

Will be rendered as

{"pair":{"name":"value"}}

2. To render an array of values, use a closure

e.g.

render(contentType:'text/json'){
	collection{
		pair(name:'value')
		pair(name:'value1')
	}
}

Will be rendered as

{collection:[{"name":"value"},{"name":"value1"}]}

Anything inside the collection closure becomes the values of the array. And because of this, the method name “pair” has no place to appear in the rendered array.

Putting It to Work

Here’s an example putting the two rules together.

render(contentType:'text/json'){
	studio(name:'Pixar',website:'pixar.com')
	films{
		film(title:'Toy Story',year:'1995')
		film(title:'Monsters, Inc.',year:'2001')
		film(title:'Finding Nemo',year:'2003')
	}
}

The result JSON will be

{"studio":{"name":"Pixar","website":"pixar.com"},
"films":[
{"title":"Toy Story","year":"1995"},
{"title":"Monsters, Inc.","year":"2001"},
{"title":"Finding Nemo","year":"2003"}
]}

When DSL is Not Enough

But there’s a gotcha about the current JSON Builder DSL to keep in mind. As of 1.0 RC3, You can have objects inside an array, but not an array inside an object (except the JSON object itself).

For example, I want a JSON structure like this.

{"object":{"collection":[{"name":"value1"},{"name":"value2"}]}}

I may write something like this,

render(contentType:'text/json'){
	object(collection{
		item(name:'value1')
		item(name:'value2')
	})
}

Although it’s syntactically correct, you will get a runtime exception of

java.lang.IllegalArgumentException: JSON Builder: not implemented
	at grails.util.JSonBuilder.createNode(JSonBuilder.java:121)
...

Oh, maybe I made a mistake, I think. The closure is not a key/value pair there. And I change the code like this

render(contentType:'text/json'){
	object(collection:{
		item(name:'value1')
		item(name:'value2')
	})
}

This looks better. Does it work? Nope. It’s not what you’d expect.

{"object":{"collection":"DummyController$_closure15_closure27_closure28@4af40c"}}

This can’t be right. Then how about

render(contentType:'text/json'){
	object(collection:collection{
		item(name:'value1')
		item(name:'value2')
	})
}

Oddly, this will be rendered as

{"collection":[{"name":"value1"},{"name":"value2"}],"object":{"collection":1}}

The Almighty JSON converter

So is there any workaround, when JSON Builder DSL fails you? Yes! You can always turn to the JSON converter. Construct a temporary Map to contain the data, and use the converter to render the map as a whole.

To correctly render the JSON data in the previous section, you can use the JSON converter this way. In your controller, use the following code.

import grails.converters.*
...
def jsonMethod = {
	...
	def json = [object:[collection:[[name:'value1'],[name:'value2']]]]
	render json as JSON
}

The result JSON will be exactly what I want

{"object":{"collection":[{"name":"value1"},{"name":"value2"}]}}

You can render any object using the JSON converter. And the results are pretty predictable.

Performance-wise, I’m not sure if there’s any difference or anyone has done any benchmark yet. So I’d say that it’s really your call which way to make your JSON. The converter doesn’t look as sexy as the DSL, but it sure works great. I may just choose either one depending on my mood:)

Grails: Sending email using Ant with GMail SMTP server

Thursday, January 10th, 2008

SMTP is one service I don’t want to burden my little site with. So I’m trying to send emails using the Gmail SMTP server.

Actually, sending emails with Grails is a breeze. There are different ways but I find that using the Ant mail task is the most effortless one. Thanks to the excellent demonstration by Glen Smith with the GroovyBlogs code, I could get started in a fraction of time. But to successfully use the GMail SMTP service, there are a few things to pay attention to.

1. Be sure to copy necessary jars to your grails-app/lib

The required jars include:

*If you are on Java 1.5 or earlier, you need the additional activation.jar. Since I’m using Java 6, it’s included in the JDK and I don’t need a copy in my lib.

2. GMail SMTP settings

This has literally cost me some hours so I hope it’s helpful to you. I at first searched for a set working settings and it turns out port 587 is the working one (for Rails). I did so but hit into mysterious exceptions with SSL.

: Problem while sending mime mail:
at groovy.util.AntBuilder.nodeCompleted(AntBuilder.java:199)
...
Caused by: javax.mail.MessagingException: Exception reading response;
nested exception is:
javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?
...

This lead me to the wrong direction and I spent some time investigating if there’s anything wrong with my config and Ant dealing with SMTP behind SSL/TLS. But finally, it turns out that port 587 was NOT being friendly to Ant over SSL. Use port 465 and it’s all good! (which is the opposite situation with Rails)

A little summary

So the complete config for GMail looks like this. (As written in Config.groovy)

mail{
  host="smtp.gmail.com"
  port="465"
  ssl="on"
  user="your.addr@gmail.com"
  password="password"
}

Use these as the params for the Ant mail task. To glue things together with Grails, you just need to

  1. Put the Ant params in Config.groovy so that they can be easily modified later.
  2. Create a service class for sending emails. e.g. MailService.groovy. Then in the service method, use AntBuilder’s DSL to create the mail task. It should look something like
    import org.codehaus.groovy.grails.commons.ConfigurationHolder as C
    ...
    new AntBuilder().mail(
      mailhost:C.config.mail.host,
      mailport:C.config.mail.port,
      ssl:C.config.mail.ssl,
      user:C.config.mail.user,
      password:C.config.mail.password,
      subject:msgSubject
    ){
      from(address:C.config.mail.reply.name)
      to(address:toAddr)
      message(mimetype:"text/html", content)
    }

That’s pretty neat, eh? If you feel like getting a peek at some working code, you can grab the GroovyBlogs source and do the modifications to talk with GMail in minutes.

Grails IDE - Eclipse vs. IntelliJ IDEA vs. NetBeans

Wednesday, December 5th, 2007

No successful technology today exists without great IDE tooling support. It’s like a law. Some tools are so great that they went beyond their original missions and became a successful technology itself. Take the ubiquitous Eclipse platform for example, it began as the donation code from IBM’s VisualAge for Java, which was supposed to be a good IDE for Java development.

In other words, I reckon the greatness of the tools is like an indicator factor for the level of maturity and popularity of the technology itself. The abundance of tech books is another such indicator.

Grails is really sweet. But it’s also very young. It just reached 1.0 RC2 yesterday. So for the curious Grails developers out there, what are the tools available for us? I’ll share my experience choosing my perfect Grails dev tool in this article.

Eclipse

First, I’m a long time Eclipse user. So I started with Eclipse. Lucky enough, we have the Groovy Eclipse plug-in which is the best (and only?) plug-in bringing Groovy support to the Eclipse world. (GroovyMonkey is the other one being “Groovy” but it’s not for serious Groovy and Grails development)

I’m using the update site for the development version (http://dist.codehaus.org/groovy/distributions/updateDev/). The latest build is 1.1.0.20071001. The plug-in is created for general Groovy development. The latest build now provides content assist, which is pretty neat and is essential for a practically usable modern IDE.

But there’s still a long wish-list and todo-list for the plug-in. To name a few, there’s still no specific support for developing Grails apps. The current way to work on Grails with it is kind of a DIY. This wiki page is the must-read for getting comfortable with Grails in Eclipse.

Also, the lack of refactoring, code formatting, and the trouble in debugging are the top most wanted missing parts. (Oh I’m so spoiled by Eclipse.)

That said, I’m still pretty happy with what I’ve already got. What’s more, the power of Eclipse brings you other wonderful tools including Aptana and Mylyn. Them together, you are good to go.

I’ll give Groovy Eclipse a 3 out of 5.

IntelliJ IDEA 7

I’ve heard of the greatness of IDEA for quite a while. Yet I’ve not really tried using it until I’m seriously looking for the best tool for Grails, the resistance mostly being its non-free-ness.

But, man! Grails tasks are already available at your fingertips. Syntax highlighting for .gsp and code formatting are neat. Content assist is of production quality. And the best, step debugging works out of the box. The IntelliJ folks are really doing a good job with the JetGroovy plugin. You can check this page on the Grails wiki to get more details.

There are some distracting issues with IDEA itself, though. For example, the startup loading and scanning taking so long that it’s crazy for a modern IDE like this. Service classes cannot get resolved in controllers while they are are marked as source folders. And I still need to get used to the funky tabs which don’t have close buttons and saves any change stealthily.

I give JetGroovy a 4 out of 5.

NetBeans 6.1

Exactly speaking, that’s NetBeans 6.1 Dev nightly build that I’ve used. The Groovy and Grails plugin is a new comer and doesn’t even show up in the latest 6.0 release. You can only find it in the plugins repository of the latest Dev build of 6.1.

And it’s really an infant and far from finished. Currently what I see it can do is nothing more than basic syntax highlighting, creating an empty Grails app and run or stop it. No menu for creating domain classes, controllers, etc. No content assist. Not to mention refactoring and debuging, which I didn’t bother to try.

I give it a 1 out of 5. It’s great NetBeans is trying. But it’s still far from usable.

The Verdict

The current choice of tooling support for Grails is still limited. IDEA is really great. But in the end I’m staying with Eclipse. It’s the Eclipse ecosystem that keeps me loyal. And I have high hopes Grails and Groovy will get better tools on Eclipse, now that the major players in the industry like IBM is already playing with Groovy in its Project Zero.

But after all, when talking about choosing the right tool, it’s always about the right tool for YOU.