NoClassDefFoundError: groovy/lang/binding

折月煮酒 提交于 2020-07-18 22:52:10

问题


I'm trying to evaluate Groovy script inside a Java app by using GroovyShell.

Problem: My program compiles ok, but gives me a NoClassDefFoundError at run-time.

TestClass.java:

import groovy.lang.Binding;
import groovy.lang.GroovyShell;

class TestClass {
    static Binding binding;
    static GroovyShell shell;

    public static void main(String[] args) {
        System.out.println("Hello, world.");
        binding = new Binding();
        shell = new GroovyShell(binding);
        Object value = shell.evaluate("5 ** 5");
    }
}

Then I compile with:

> javac -cp %GROOVY_HOME%\embeddable\groovy-all-2.1.1.jar TestClass.Java

> jar cfm TestClass.jar Manifest.txt TestClass.class

It compiles without error. Then I run it:

> java -jar TestClass.jar

Hello, world
Exception in thread "main" java.lang.NoClassDefFoundError: groovy/lang/Binding
    at TestClass.main(TestClass.java:10)
Caused by: java.lang.ClassNotFoundException: groovy.lang.Binding
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)

Full error text: http://puu.sh/2gOrx

I've also tried running it with the same -cp as I compiled it, but it gives me the same error.


回答1:


Global classpath, for example, CLASSPATH environment and "-cp" option, won't take affect if you are running an executable JAR. Please refer to this post for details: Does java -jar option alter classpath options.

java - the Java application launcher document

When you use this option, the JAR file is the source of all user classes, and other user class path settings are ignored.

Instead, you need to set Class-Path in manifest file. Check the following sample.

File structure

|-- Manifest.txt
|-- TestClass.class
|-- TestClass.jar
|-- TestClass.java
`-- lib
    `-- groovy-all-2.1.1.jar

Manifest.txt (don't forget to add a new line ending for last line)

Main-Class: TestClass
Class-Path: lib/groovy-all-2.1.1.jar

And execute the same commands in your question to generate and run an executable JAR. For more information, check this wiki page: Setting the path in a Manifest file.




回答2:


Instead of running the JAR directly, load the JAR into the classpath and specify the class to run:

$ java -classpath $groovyJar:TestClass.jar TestClass

It's a little hacky because the Main-Class is specified in the manifest but then taken from the command line. On the plus side, you don't have to hard-code the Class-Path into the manifest.

The path to the Groovy JAR has changed since this question was asked a very long time ago. Assuming groovy is in your PATH, one way to locate the Groovy JAR is:

$ groovyHome=$(dirname $(dirname $(which groovy)))
$ groovyJar=$groovyHome/lib/$(basename $groovyHome).jar

And the result will be something like:

$ which groovy
/Users/dem/apps/groovy/groovy-2.5.2/bin/groovy
$ echo $groovyJar
/Users/dem/apps/groovy/groovy-2.5.2/lib/groovy-2.5.2.jar

To build a JAR you can test with locally, create the Groovy file:

com/example/HelloWorld.groovy

package com.example

class HelloWorld {

   static void main(String[] args) {
      println "Hello, world."
   }

}

Then issue the commands:

$ groovyc com/example/*.groovy
$ jar cfv HelloWorld.jar com/example/*.class
added manifest
adding: com/example/HelloWorld.class(in = 2829) (out= 1220)(deflated 56%)
$ ls -o
total 8
-rw-r--r--  1 dem  1708 Oct  5 01:15 HelloWorld.jar
drwxr-xr-x  3 dem    96 Oct  5 01:10 com
$ java -classpath $groovyJar:HelloWorld.jar com.example.HelloWorld
Hello, world.

Note: The Groovy JAR (groovy-2.5.2.jar) is 5.4MB, and the latest version (groovy-3.0.0-alpha-3.jar) is 7.5MB.



来源:https://stackoverflow.com/questions/15399522/noclassdeffounderror-groovy-lang-binding

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!