Andre van der Schyff

My online home and blog

Groovlet for executing arbitrary Groovy on the server

Source for this post can be downloaded from here, with usage instructions at the bottom of this post (you’ll need Maven),

I attended a talk on Groovy at JUGSA last week, during which the presenter mentioned that in their latest project, they included a Servlet that allows them to run arbitrary Groovy on the server. It just opens a text box where you can paste in your Groovy code, and it executes it dynamically on the JVM. Now, if you need this to keep your server going you are probably doing something very wrong, but just in terms of the sheer power this gives you to do stuff on the server, and specifically inside the JVM, I can’t really think of much that comes close.

So, as I’ve been wanting to try some Groovy for a while now, I’ve decided to give it a go myself. I also thought that it would be neat to do the Servlet in Groovy, and quickly found the most sensible way to do this is with a Groovlet, which appears to be the Groovy equivalent of Servlet. These were easy enough to get going, just add a servlet mapping to your web.xml file:

<servlet>
<servlet-name>Groovy</servlet-name>
<servlet-class>groovy.servlet.GroovyServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>Groovy</servlet-name>
<url-pattern>*.groovy</url-pattern>
</servlet-mapping>

This servlet will now pick up anything requested with *.groovy in between your regular JSP’s or HTML, and run it as a Groovlet.

The Groovlet itself was quite easy to do, I actually based mine on the ‘Hello World’ example from the Groovy site. The first bit checks for submitted script, if any submitted script is found it is executed. Right now I’m capturing the output by redirecting System.out, no doubt Groovy has a much more clever way of doing this but I could not find it in 5 minutes of Googling. What may also be of interest is that I’m using GroovyShell to execute the script, Groovy actually supplies a number of other ways of doing this.

script = request.getParameter("groovyscript");
scriptOutput = new ByteArrayOutputStream()

if (script) {
// Redirect output
saveOut = System.out

System.out = new PrintStream(scriptOutput)
result = new GroovyShell().run(script, "dynamic.groovy");
System.out = saveOut

}

The second bit in the same file produces the form on which the script is captured, and prints out any output from while System.out was redirected. This is all done with one big println, Groovy has some nice support for using Strings with variables in an intuitive way.

println """

Groovy Servlet

<form action="${request.requestURL}" method="post">
<h2>Groovy Servlet</h2>
Code comes here:

<textarea cols="120" rows="25" name="groovyscript">${script ? script : ""}</textarea>

<input type="submit" value="Go!" />

</form>${scriptOutput.toString() ? "
<h2>Output</h2>
${scriptOutput}" : ""}

"""

And that’s it! So, why would you want to do this? Is it not incredibly dangerous? Well, the short answer to that would be yes, however, as long as it’s only accessible to your developers, it’s probably less dangerous than giving them access to the server via SSH or a SQL console. At least you’re playing in your own domain, where things are nicely encapsulated and the code stops at least some very bad things from happening. In return, you get to evaluate things in your running JVM without actually attaching a debugger. This is a powerful tool to figure out what’s going on in a complex system. If you’re using Spring, for example, you would extend the Servlet to load your application context, which pretty much allows you to do whatever you want without needing to do a deploy. Of course, you will only be limited by your own common sense, and if you do stupid things you will get burnt.

Source code: Usage:

  1. Unpack the tarball: tar -xzvf groovyweb.tar.gz
  2. cd groovyweb
  3. mvn install jetty:run
  4. Point your browser to http://localhost:8080/groovyweb

18 Responses to “Groovlet for executing arbitrary Groovy on the server”

Leave a Reply