How to invoke groovy with 'java' from comm

2019-02-03 07:38发布

问题:

I have to ship some groovy code to some users that have only java installed (no grooy, no $groovy_home, etc). I'm trying to invoke groovy from the commandline but I'm having no luck. Here's my bat file:

java -classpath .;lib;bin;bin-groovy introspector.AclCollector

And here's my exception:

Exception in thread "main" java.lang.NoClassDefFoundError: groovy/lang/GroovyObject
       at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:621)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:260)
        at java.net.URLClassLoader.access$000(URLClassLoader.java:56)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:195)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
        at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
Caused by: java.lang.ClassNotFoundException: groovy.lang.GroovyObject
        at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
        at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
        ... 12 more
Could not find the main class: introspector.AclCollector.  Program will exit.

Does anyone have a clue? I have 'groovy-all-1.6-beta-1.jar' in \lib dir.

回答1:

I think you need to explicitly list the groovy jar in the classpath



回答2:

You have here another example of Groovy app called from Java (in this case, from ant, but the general idea is the same).

java -cp [...];%GROOVY_HOME%/embeddable/groovy-all-1.5.4.jar;[..]

As mentioned by frankowyer, you have the exact groovy jar explicitly listed on the classpath arguments of the java.

Since your clients do not have special environment variable, just replace the %GROOVY_HOME%/... with the complete path to:

  • groovy.jar or
  • goovy-all-VERSION.jar (to minimize any conflict with other libraries)


回答3:

One way to avoid problems with different class paths on different machines would be to bundle all the necessary dependencies into one single jar, this would also make distribution to users easier. This can be done with this 'GroovyWrapper' script. The default jars (embeddable/groovy-all-.jar and lib/commons.jar) are included by default in the script and if you require other JARS they can easily be added.

See http://docs.codehaus.org/display/GROOVY/WrappingGroovyScript for the full script and instructions.

Here's an example of how to use GroovyWrapper:

Say you have groovy script HelloWorld.groovy, use GroovyWrapper for building HelloWorld.jar, as follows:

$ groovy GroovyWrapper -c -m HelloWorld

GroovyWrapper will compile the script HelloWorld.groovy to HelloWorld.class, and creates a self-executable jar HelloWorld.jar.

Now you can use the HelloWorld.jar for launching the HelloWorld script, simply by running:

$ java -jar HelloWorld.jar


回答4:

GREAT ANSWER by VonC:

....... Since your clients do not have special environment variable, just replace the %GROOVY_HOME%/... with the complete path to:

groovy.jar or
goovy-all-VERSION.jar (to minimize any conflict with other libraries)........

this is for windows Vista:

In System Properties | Environmental Variables | User variables: Variable Name GROOVY_HOME set to C:\groovy\Groovy-1.8.5 and the Variable Name CLASSPATH value's set to include .;%GROOVY_HOME%\embeddable\groovy-all-1.8.5.jar

Don't make the mistake I did(spinning my wheels a bit), of not prep-ending the path of the 'groovy-all' with ".;" (dot and semi-colon): as the path needs the base folder you're in for finding the main class(strange as it seems)



回答5:

Watch out of [~]!

java -cp .:~/path-to-groovy-all.jar YourClassName     # does not work
java -cp ~/path-to-groovy-all.jar:. YourClassName     # works
java -cp .:/full/path/to/goovy-all.jar YourClassName  # works

In first line tilde is not processed by bash, and java can not understand it.

In second line tilde is replaced by bash and everything works fine.