Search code examples
groovy

Why doesn't groovy use classpath argument?


Invoking a groovy script using CLASSPATH prefix as follows works fine:

CLASSPATH=/path/to/classes groovy -e "(new stuff.XMLUtils()).printIt('test string')"

but changing it to use the classpath arg doesn't:

groovy -classpath /path/to/classes -e "(new stuff.XMLUtils()).printIt('test string')"

and gives the error:

script_from_command_line: 1: unable to resolve class stuff.XMLUtils

Can anyone explain why this is? (The stuff.XMLUtils is just some groovy script i've compiled into /path/to/classes )

I've done some investigation, and using the following groovy script to dump the classloader

def printClassPath(classLoader) {
  println "$classLoader"
  classLoader.getURLs().each {url->
     println "- ${url.toString()}"
  }
  if (classLoader.parent) {
     printClassPath(classLoader.parent)
  }
}
printClassPath this.class.classLoader

With the -classpath arg, i see no entry in the classloader for the passed in classpath arg, (in fact, the only directory is the current working dir), e.g.:

groovy.lang.GroovyClassLoader$InnerLoader@4911b910
groovy.lang.GroovyClassLoader@18203c31
sun.misc.Launcher$AppClassLoader@35a16869
- file:/usr/share/java/ant.jar
- ... (removed for brevity)
- file:/home/admin/groovy/
sun.misc.Launcher$ExtClassLoader@77cde100
- file:/usr/java/jdk1.6.0_23/jre/lib/ext/sunjce_provider.jar
- ...

Using the CLASSPATH=... version shows that the PWD entry above is replaced by the value i've set in the variable.

And if I add debug to the groovy shell executable, the difference in the java call is that the -classpath arg version adds no entry to java's classpath entry (which is ultimately why it's giving a class not found error), but the CLASSPATH=... version does add the path.

Is this a bug in groovy?

EDIT: simple failing example

- - - - xu.groovy
package stuff
def printIt(string) { println string }
- - - -

groovyc -d classes xu.groovy
groovy -cp classes -e "(new stuff.xu()).printIt('test')"  # fails
CLASSPATH=classes groovy -e "(new stuff.xu()).printIt('test')"  # works

If I remove the package and references to stuff the failing example will work fine.


Solution

  • Answering this myself because I found a solution to the problem.

    I was using the default groovy packages from yum in fedora, however found many issues (errors starting groovysh etc, unable to find jline package etc), and have wholly moved over to using downloaded versions from codehaus.org, and manually specifying GROOVY_HOME and editing path to invoke the downloaded one instead.

    Now all my examples work as expected.