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.
It is impractical for it to go through every folder on your system and search for it. Thus, using the CLASSPATH variable we provide it the place where we want it to look. We put directories and jars in the CLASSPATH variable.
[:] creates an empty Map. The colon is there to distinguish it from [] , which creates an empty List. This groovy code: def foo = [:]
The default value of CLASSPATH is a dot (.). It means the only current directory searched. The default value of CLASSPATH overrides when you set the CLASSPATH variable or using the -classpath command (for short -cp). Put a dot (.)
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.
I'm on MSYS/Win32 + groovy 2.2 RC1 and have another twist:
groovy -cp "./*" script.groovy // Works!
but
groovy -cp some.jar script.groovy // ... not
For some reason, none of the above would work out in my case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With