4

我正在尝试使用 GroovyShell 在 Java 应用程序中评估 Groovy 脚本。

问题:我的程序编译正常,但在运行时给了我一个 NoClassDefFoundError。

测试类.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");
    }
}

然后我编译:

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

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

它编译没有错误。然后我运行它:

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

完整的错误文本: http: //puu.sh/2gOrx

我也尝试使用与编译它相同的 -cp 运行它,但它给了我同样的错误。

4

2 回答 2

4

全局类路径,例如 CLASSPATH 环境和“-cp”选项,如果您正在运行可执行 JAR,则不会生效。有关详细信息,请参阅此帖子:Does java -jar option alter classpath options

java - Java 应用程序启动器文档

使用此选项时,JAR 文件是所有用户类的来源,其他用户类路径设置将被忽略。

相反,您需要在清单文件中设置 Class-Path。检查以下示例。

文件结构

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

Manifest.txt(不要忘记为最后一行添加一个新行结尾)

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

并在您的问题中执行相同的命令以生成并运行可执行 JAR。有关更多信息,请查看此 wiki 页面:在清单文件中设置路径

于 2013-03-14T03:52:15.367 回答
0

不要直接运行 JAR,而是将 JAR 加载到classpath并指定要运行的类:

$ java -classpath $groovyJar:TestClass.jar TestClass

这有点hacky,因为Main-Class在清单中指定但随后从命令行获取。从好的方面来说,您不必将其硬编码Class-Path到清单中。

自从很久以前提出这个问题以来, Groovy JAR的路径已经改变。假设groovy在您的PATH中,定位 Groovy JAR 的一种方法是:

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

结果将是这样的:

$ 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

要构建可以在本地测试的 JAR,请创建 Groovy 文件:

com/example/HelloWorld.groovy

package com.example

class HelloWorld {

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

}

然后发出命令:

$ 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.

注意: Groovy JAR ( groovy-2.5.2.jar) 为 5.4MB,最新版本 ( groovy-3.0.0-alpha-3.jar) 为 7.5MB。

于 2018-10-05T08:44:56.580 回答