groovygroovyscriptengine

Groovy script won't run due to NoClassDefFoundError


I wrote a very simple groovy script to test if a cron expression is valid:

import hudson.scheduler.CronTabList

try {
    def cron = CronTabList.create("@daily")
    println("Valid cron!")
} catch(Exception e) {
    println("Invalid cron!")
    e.printStackTrace()
}

Running this fails with the message:

Caught: java.lang.NoClassDefFoundError: javax/servlet/ServletContextListener
java.lang.NoClassDefFoundError: javax/servlet/ServletContextListener
    at hudson.scheduler.BaseParser.<clinit>(BaseParser.java:149)
    at hudson.scheduler.CronTab.set(CronTab.java:113)
    at hudson.scheduler.CronTab.<init>(CronTab.java:100)
    at hudson.scheduler.CronTabList.create(CronTabList.java:121)
    at hudson.scheduler.CronTabList.create(CronTabList.java:96)
    at hudson.scheduler.CronTabList$create.call(Unknown Source)
    at validate_crontab.run(validate_crontab.groovy:7)
Caused by: java.lang.ClassNotFoundException: javax.servlet.ServletContextListener
    ... 7 more

Process finished with exit code 1

My build.gradle dependencies look like:

dependencies {
    compile 'org.codehaus.groovy:groovy-all:2.3.11'
    compile group: 'org.quartz-scheduler', name: 'quartz', version: '2.3.0'
    compile group: 'org.jenkins-ci.main', name: 'jenkins-core', version: '2.85'
    testCompile group: 'junit', name: 'junit', version: '4.12'
}

I simply can't figure out what's to blame and why I can't run the script.

Any help is much appreciated!


Solution

  • Apparently what you miss is the servlet API. For example:

    dependencies {
        compile group: 'javax.servlet', name: 'javax.servlet-api', version: '3.1.0'
    }
    

    If you put that in your dependencies your script will most likely run.

    But I guess that it is fairly important to understand why did you get this error. If you have a closer look at the jenkins-core library you will notice that it has a "provided" dependency to the servlet API. A provided dependency in simpler words means that the library (jenkins-core in your case) is compiled with the assumption that the servlet API jar will be present in the class path at your production environment - e.g. when using the lib in a web application running within a servlet container.

    I guess that you run your groovy script as a standalone app, that is why you are getting an error. And... DISCLAIMER - I do not know if using jenkins-core in standalone apps is intended, though :-).