javagroovytemplate-enginegstring

Groovy classloader exception when using template engine


I'm new to Groovy and tried to use the GStringTemplateEngine to execute some groovy scripts on JBoss 5.1

Everything works fine in my local development environment, but fails when moved to the dev server managed by a different team.

I found that the exception is thrown specifically at

try {
    groovyClass = loader.parseClass(new GroovyCodeSource(templateExpressions.toString(), "GStringTemplateScript" + counter.incrementAndGet() + ".groovy", "x"));
} catch (Exception e) {
    throw new GroovyRuntimeException("Failed to parse template script (your template may contain an error or be trying to use expressions not currently supported): " + e.getMessage());
}

on GStringTemplateEngine.class, line 190

The exception message is

groovy.lang.GroovyRuntimeException: startup failed:
General error during class generation: URI is not hierarchical

java.lang.IllegalArgumentException: URI is not hierarchical
    at java.io.File.<init>(File.java:363)
    at org.jboss.net.protocol.file.FileURLConnection.<init>(FileURLConnection.java:62)
    at org.jboss.net.protocol.file.Handler.openConnection(Handler.java:40)
    at java.net.URL.openConnection(URL.java:945)
    at java.net.URLClassLoader.getPermissions(URLClassLoader.java:474)
    at groovy.lang.GroovyClassLoader.getPermissions(GroovyClassLoader.java:335)
    at java.security.SecureClassLoader.getProtectionDomain(SecureClassLoader.java:235)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
    at groovy.lang.GroovyClassLoader.access$300(GroovyClassLoader.java:55)
    at groovy.lang.GroovyClassLoader$ClassCollector.createClass(GroovyClassLoader.java:475)
    at groovy.lang.GroovyClassLoader$ClassCollector.onClassNode(GroovyClassLoader.java:492)
    at groovy.lang.GroovyClassLoader$ClassCollector.call(GroovyClassLoader.java:496)
    at org.codehaus.groovy.control.CompilationUnit$14.call(CompilationUnit.java:792)
    at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:1024)
    at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:562)
    at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:540)
    at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:517)
    at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:283)
    at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:260)
    at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:244)

I'm not sure why its throwing a URI not hierarchical error. I'm assuming it has something to do with permissions and GroovyClassLoader is not able to parse the generated class.

Has anyone seen this error before? It would be helpful if someone can provide some suggestions on debugging/fixing the issue.


Solution

  • Not sure of the real cause of the issue, but found a workaround.

    Created a copy of GStringTemplateEngine and replaced

    try {
        groovyClass = loader.parseClass(new GroovyCodeSource(templateExpressions.toString(), "GStringTemplateScript" + counter.incrementAndGet() + ".groovy", "x"));
    } catch (Exception e) {
        throw new GroovyRuntimeException("Failed to parse template script (your template may contain an error or be trying to use expressions not currently supported): " + e.getMessage());
    }
    

    with

    try {
        groovyClass = loader.parseClass(templateExpressions.toString(), "GStringTemplateScript" + counter.incrementAndGet() + ".groovy");
    } catch (Exception e) {
        throw new GroovyRuntimeException("Failed to parse template script (your template may contain an error or be trying to use expressions not currently supported): " + e.getMessage());
    }
    

    Removed GroovyCodeSource and passed template string instead to the parseClass method.