Pandora’s Box for Liferay: The Groovy Edition

In the beginning of the year I had some fun creating the CRaSH portlet. Once it is deployed, it allows a portal administrator to work with the portal/JVM in a very flexible way using a command line syntax. While this is a very powerful portlet, there are some drawbacks. You need to be able to install it and you need to already have or develop a number of additional commands to make it useful for your specific use case.

This makes the CRaSH portlet difficult to use in some situations, e.g. an audit of an existing Liferay platform, where you might not have the access or permissions to even install it. So what can you do if you need to find out some information about the actual server that Liferay is installed on without SSH access? You try to use the Liferay Script Portlet of course! In my case using my favorite script language: Groovy.

I used 2 scripts for this in the past. The first one lists the contents of a directory:

import java.io.*;
 
try {
   File directory = new File("/export/liferay_dev2/data");
   for (File f : directory.listFiles()) {
      out.println(f.name + " " + f.size());
   }
} catch (Exception e) {
   out.println(e.getMessage());
}

The second one lists the contents of a file:

try {
   java.io.File file = new java.io.File("/opt/liferay/portal-ext.properties");
   String s = com.liferay.portal.kernel.util.FileUtil.read(file);
   out.println(s);
} catch (Exception e) {
   out.println(e.getMessage());
}

While these 2 scripts do their job perfectly, they are a bit of a hassle to use when you want to traverse a big directory tree and look at a lot of files. This way of working allows you to look at /etc/release to find out the version of the operating system. However, it doesn’t allow you to actually execute a shell command like apt-get –just-print upgrade to find out how up-to-date the version of the operating system is.

The Groovy solution

Groovy is very powerful and so my (educated) guess was that there must be something in the scripting language that could help me with this problem. After looking around for a bit, I found a Stack Overflow post and after tweaking the script from it a tiny bit, I ended up with the following script:

def sout = new StringBuilder(), serr = new StringBuilder()
def proc = 'apt-get --just-print upgrade'.execute()
proc.consumeProcessOutput(sout, serr)
proc.waitForOrKill(10000)
println "out>"
println "$sout"
println "err>"
println "$serr"

This Groovy script allows you to execute any shell command that a Liferay user could want to execute. It will print its output and error streams below the script portlet.

You can just change line 2 of the script and easily run other commands like ls, tail, cat, whoami, etc…

Blogs