Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't groovy use classpath argument?

Tags:

groovy

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.

like image 352
Mark Fisher Avatar asked Feb 22 '12 11:02

Mark Fisher


People also ask

Why is classpath needed?

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.

What does [:] mean in Groovy?

[:] creates an empty Map. The colon is there to distinguish it from [] , which creates an empty List. This groovy code: def foo = [:]

What should classpath be set to?

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 (.)


2 Answers

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.

like image 69
Mark Fisher Avatar answered Nov 02 '22 00:11

Mark Fisher


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.

like image 29
Simon Thum Avatar answered Nov 02 '22 02:11

Simon Thum