Shared Grails JARs for Tomcat deployment

While I was at GR8Conf US, one of the attendees asked me how to deploy two Grails WAR files to Tomcat without running into the dreaded “out of permgen space” error. This problem stems from Grails apps loading a lot of classes, and each webapp gets its own copy of those classes. So that’s pretty much double the permgen usage when you deploy two Grails WARs to a single Tomcat instance.

The common solution to this problem is to put the library JARs common to all Grails applications into Tomcat’s shared lib directory. Then there will only be one copy of the corresponding classes loaded in the VM regardless of how many webapps are deployed. It’s a pretty neat solution considering how many common JARs there are between Grails apps, but Grails throws in an additional challenge in that some per-application state is actually per-VM state. So deploying more than one Grails WAR into a Tomcat with shared Grails JARs can cause issues.

A quick web search brings up this question on StackOverflow with a corresponding list of the JARs that can be shared and those that can’t. Certainly for Grails 2.0+, it seems that only the grails-* JARs are unsafe, so I came up with a short events script that splits the JARs, putting the Grails ones in the WAR file and the rest in a sharedLibs directory:

eventCreateWarStart = { warName, stagingDir ->
    if (grailsEnv == "production") {
        def sharedLibsDir = "${grailsSettings.projectWorkDir}/sharedLibs"

        ant.mkdir dir: sharedLibsDir
        ant.move todir: sharedLibsDir, {
            fileset dir: "${stagingDir}/WEB-INF/lib", {
                include name: "*.jar"
                exclude name: "grails-*"

        println "Shared JARs put into ${sharedLibsDir}"

Note that this fragment goes into the scripts/_Events.groovy file in the Grails project. I hope it helps folks!

2 thoughts on “Shared Grails JARs for Tomcat deployment

Leave a Reply

Your email address will not be published. Required fields are marked *