Gradle classloader problems with Jetty plugin

This problem manifested itself during resolution of a different problem when upgrading to Gradle 1.0M6 from 1.0M3. I’m using a templating engine called Thymeleaf (http://thymeleaf.org/) in a webapp. The templating engine has an optional dependency on NekoHTML that in turn depends on Xerces XML parser. I’m not using this dependency.

When I run the webapp using the ‘jettyRun’ task I get the following exception:

java.lang.NoClassDefFoundError: org/apache/xerces/parsers/DOMParser
 at java.lang.ClassLoader.defineClass1(Native Method)
 at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
 at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
 at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
 at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
 at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
 at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
 at java.security.AccessController.doPrivileged(Native Method)
 at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
 at org.gradle.util.MultiParentClassLoader.loadClass(MultiParentClassLoader.java:46)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:295)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:295)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
 at org.mortbay.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:401)
 at org.mortbay.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:363)
 at org.thymeleaf.TemplateParser.computeIsNekoInClassPath(TemplateParser.java:169)
 at org.thymeleaf.TemplateParser.<init>(TemplateParser.java:106)
 at org.thymeleaf.TemplateEngine.initialize(TemplateEngine.java:671)
 at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:767)
 at org.thymeleaf.spring3.view.ThymeleafView.render(ThymeleafView.java:201)

This is because the ‘org.thymeleaf.TemplateParser’ attempts to find nekohtml on the classpath using the method: ‘computeIsNekoInClassPath()’ which calls:

try {
    Thread.currentThread().getContextClassLoader().loadClass("org.cyberneko.html.parsers.DOMParser");
    return true;
} catch (ClassNotFoundException e) {
    return false;
}

This call appears to have problems computing the classpath with the ‘org.gradle.util.MultiParentClassLoader.loadClass()’ method. I’ve attached a full example project that reproduces the error consistently here:

https://dl.dropbox.com/s/2kmvxxgv9w8vrtd/thymeleaf-project.zip

Any and all help is appreciated.

There’s really not much more information I can provide… I built the latest Gradle 1.0M7 release from the master branch on the git repository. The problem still exists on there as well.

I ran into the same problem… have you managed to work around this?

Hey Nadav,

Unfortunately I never found a workaround for it, I had to start using the Jetty Runner (http://blogs.webtide.com/janb/entry/jetty_runner) project to spin up a quick Java web server during development. I did open an issue on the Gradle Issue Tracker here:

http://issues.gradle.org/browse/GRADLE-1960

But ever since I’ve opened the issue, it’s scheduled fix version has been bumped by the Gradle developers.

Chris,

Got good news from the good folks of Thymeleaf - they’ve solved this issue for their next version.

See this link for details:

http://forum.thymeleaf.org/Thymyleaf-Gradle-Jetty-td4024844.html#a4024886

Hey Nadav,

Thanks very much for the link and the update on the issue. I’ve been using Gradle for quite a while (since 0.7 days) and originally the project worked fine. As the build tool matured they added parallisation of builds, this is when the classloading issues began to occur. I’d assumed that it was a strange classloading bug introduced by Gradle that caused this problem.

I’ve added the Sonatype Snapshot Repository to my build environment and have tested Thymeleaf 2.0.11-SNAPSHOT with success while using the Jetty plugin.

Thanks for your help.