【问题标题】:NoClassDefFoundError: groovy/lang/bindingNoClassDefFoundError: groovy/lang/binding
【发布时间】:2013-03-02 05:26:10
【问题描述】:

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

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

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");
    }
}

然后我编译:

> 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 来运行它,但它给了我同样的错误。

【问题讨论】:

  • 你可以试试“java -cp TestClass.jar;%GROOVY_HOME%\embeddable\groovy-2.1.1.jar TestClass”吗?
  • 同样的错误。 puu.sh/2hlYG
  • %GROOVY_HOME%\embeddable\groovy-2.1.1.jar 是否存在?在我这边,它是 groovy-all-2.1.1.jar。
  • 哦,我实际上应该使用 groovy-all-2.1.1.jar。不过我在帖子里打错了。 puu.sh/2hn9E

标签: java groovy jar classpath


【解决方案1】:

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

java - the Java application launcher document

使用此选项时,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 页面:Setting the path in a Manifest file

【讨论】:

    【解决方案2】:

    不要直接运行 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。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-05
      • 2012-08-02
      • 1970-01-01
      • 2012-03-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多