Monday, March 7, 2011

Grails, Tomcat and additional contexts

I needed to create a modular application today. It was nice and easy up to the point where I needed to make some ajax calls and due to the same-origin principle it was all failing miserably in development. In production, since both apps are on the same tomcat instance everything works just fine.

To be able to add more contexts to the very lonely tomcat instance fired by Grails create a _Events.groovy file in your scripts folder with content like this
eventConfigureTomcat = {tomcat ->
def ctxName = "secondary"
def ctx = tomcat.addContext("/${ctxName}", System.getProperty("java.io.tmpdir"))
def servlet = tomcat.addServlet(ctx, "my-servlet", new MyServlet())
servlet.addInitParameter("some-param", "some-value")
ctx.addServletMapping("/*", "my-servlet")
}


Here's some explanation:

1. This will bring up a secondary context called "secondary" (so you can access it under http://localhost:8080/secondary)
2. It will bind to all requests below this url to MyServlet instance

Using the HttpProxyServlet I'm now able to have the secondary applications available on the same tomcat instance:
import com.jsos.httpproxy.HttpProxyServlet

def map(tomcat, ctxName, port) {
def ctx = tomcat.addContext("/${ctxName}", System.getProperty("java.io.tmpdir"))
def servlet = tomcat.addServlet(ctx, "proxy", new HttpProxyServlet())
servlet.addInitParameter("host", "http://localhost:${port}/")
servlet.addInitParameter("uri", "/")
ctx.addServletMapping("/*", "proxy")
}

eventConfigureTomcat = {tomcat ->
println "Configuring tomcat"
map(tomcat, "first", 8081)
map(tomcat, "second", 8082)
}


Hope this will give you more flexibility doing stuff with Grails!

2 comments:

fluxon said...

Hi!

Would you also have a hint on how to just add some parameters to the context that my "normal" grails app when started with "grails run-app" is using?

Specifically I want to set the "sessinCookieDomain" parameter. But I cannot figure out how to do that!

Thanks in advance for your time and your support! :)

Matthias Hryniszak said...

Did you try

ctx.sessionCookieDomain = "myotherdomain.com"

???