arcdegree
arcdegree

Reputation: 2720

Setup Embedding Tomcat in Grails to Follow Symlinks

The simplified question to this post is:

How can I access files outside the WEB-APP directory in Grails?

I have a grails application that has some shared resources (images) with another system. So I created a symlink pointing to the new files. These files are uploaded by the user so they are intentionally put outside the web-root.

For example:

/images/country_flags/ --> /some/directory/with/images/country_flags/

So when tomcat requests the image:

/images/country_flags/flag1.png

It really goes to:

/some/directory/with/images/country_flags/flag1.png

I understand that Tomcat by default does not support symlinks, but it can be enabled by creating a context.xml file in the META-INF directory with the following information:

<?xml version="1.0" encoding="UTF-8"?>

<Context path="/images" allowLinking="true"></Context>

Grails allows the configuration of Tomcat by creating a new file called "_Events.groovy" in the scripts directory.

From looking around the Internet, this should do the trick:

eventConfigureTomcat = {tomcat ->
    println "Changing the configuration for tomcat"
    println serverContextPath

    def ctx=tomcat.host.findChild(serverContextPath) 
    ctx.allowLinking = true 
    println "Configuration changed"
} 

However, I get the following output in the console:

Changing the configuration for tomcat
/
| Error Exception occurred trigger event [ConfigureTomcat]: Cannot set property 'allowLinking' on null object (Use --stacktrace to see the full trace)

My application.properties file is as follows (note the context is changed to "/"):

#Grails Metadata file
#Wed Sep 26 09:56:39 BST 2012
app.context=/
app.grails.version=2.1.1
app.name=SomeCoolApp
app.version=0.1
plugins.google-visualization=0.5.3
plugins.mail=1.0
plugins.quartz=1.0-RC2
plugins.searchable=0.6.3
plugins.spring-security-core=1.2.7.3

Neither of these methods work. Can someone point me to the documentation on how to configure Tomcat using the _Events.groovy method. Is there a way to troubleshoot why the context is null besides trying to print out to the console?

Upvotes: 2

Views: 1383

Answers (3)

Peter
Peter

Reputation: 1260

None of the answers quite worked for me but Tobia's comment helped me set the ctx variable correctly. In the end, I only had to edit the scripts/_Events.groovy like this:

eventConfigureTomcat = { tomcat ->
    def ctx = tomcat.host.findChildren()[0] 
    ctx.allowLinking = true
    println "Added symbolic link support for /${grailsSettings.config.grails.appName}"
}

Upvotes: 0

Jochen Bedersdorfer
Jochen Bedersdorfer

Reputation: 4122

This is what worked for me on Grails 2.4.x:

In BuildConfig.groovy:

grails.appName = appName;

(Not sure how else to access app name. You can also add your app.context in a similar fashion) Then add scripts/_Events.groovy with this content:

eventConfigureTomcat = { tomcat ->
    def ctx = tomcat.host.findChild("/${grailsSettings.config.grails.appName}")
    ctx.allowLinking = true
    println "Added symbolic link support for /${grailsSettings.config.grails.appName}"
}

Upvotes: 1

arcdegree
arcdegree

Reputation: 2720

I found the answer, but I don't quite understand why it works. I changed the context from serverContextPath (which returns /) to "" and it works.

eventConfigureTomcat = {tomcat ->
    println "Changing the configuration for tomcat"
    println serverContextPath

    def ctx=tomcat.host.findChild(serverContextPath) // doesn't work?
    def ctx=tomcat.host.findChild("") // works
    ctx.allowLinking = true 
    println "Configuration changed"
} 

Upvotes: 1

Related Questions