【问题标题】:java.lang.NoClassDefFoundError: groovy/lang/Script but class is loaded...?java.lang.NoClassDefFoundError: groovy/lang/Script 但类已加载...?
【发布时间】:2022-01-26 00:24:15
【问题描述】:

我在尝试用 groovy 制作 shell 时遇到问题。我正在使用 groovy 3.0.9 并正在用我的 jar 编译它。

有问题的代码:

public class GrPlayerShell extends PlayerShell {
    private final Groovysh groovysh;
    private final PrintStream out;
    private final PrintStream err;
    protected GrPlayerShell(UUID uuid) {
        super(uuid, GrShell.getInstance());
        out = new PrintStream(new PlayerStream(uuid, false));
        err = new PrintStream(new PlayerStream(uuid, true));
        this.groovysh = new Groovysh(new IO(
                new InputStream() {
                    @Override
                    public int read() throws IOException {
                        throw new IOException("Not implemented");
                    }
                },
                out,
                err));
    }

    @Override
    public void doExecute(String command) {
        execute(command);
    }

    @Override
    public Result execute(String command) {
        if (command == null || command.isEmpty()) {
            return Result.EMPTY;
        }
        Object result = groovysh.execute(command); // FIXME: 12/26/21 NoClassDefFoundError: groovy.lang.Script
        return new Result(String.valueOf(result));
    }
}

(也是here

doExecuteexecute 在不同的线程中运行,以防止 shell 在 shell 需要一段时间才能执行时暂停一切(例如 while (true) {})。

这个 jar 也会在运行时动态加载。

我已经用 java 8 和 17 进行了测试,但两者给出的结果完全相同。

只要把错误信息包起来就可以了:

org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
General error during instruction selection: java.lang.NoClassDefFoundError: groovy/lang/Script

java.lang.RuntimeException: java.lang.NoClassDefFoundError: groovy/lang/Script
    at org.codehaus.groovy.control.CompilationUnit$IPrimaryClassNodeOperation.doPhaseOperation(CompilationUnit.java:976)
    at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:671)
    at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:635)
    at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:389)
    at groovy.lang.GroovyClassLoader.lambda$parseClass$3(GroovyClassLoader.java:332)
    at org.codehaus.groovy.runtime.memoize.StampedCommonCache.compute(StampedCommonCache.java:163)
    at org.codehaus.groovy.runtime.memoize.StampedCommonCache.getAndPut(StampedCommonCache.java:154)
    at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:330)
    at groovy.lang.GroovyShell.parseClass(GroovyShell.java:526)
    at groovy.lang.GroovyShell.parse(GroovyShell.java:538)
    at groovy.lang.GroovyShell.parse(GroovyShell.java:570)
    at groovy.lang.GroovyShell$parse$0.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:148)
    at org.apache.groovy.groovysh.Interpreter.evaluate(Interpreter.groovy:76)
    at org.apache.groovy.groovysh.Evaluator$evaluate.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:139)
    at org.apache.groovy.groovysh.Groovysh.execute(Groovysh.groovy:204)
    at uwu.smsgamer.serverscripter.groovy.shell.GrPlayerShell.execute(GrPlayerShell.java:67)
    at uwu.smsgamer.serverscripter.groovy.shell.GrPlayerShell.doExecute(GrPlayerShell.java:58)
    at uwu.smsgamer.serverscripter.shell.PlayerShell$1.run(PlayerShell.java:86)
    at java.util.TimerThread.mainLoop(Timer.java:555)
    at java.util.TimerThread.run(Timer.java:505)
Caused by: java.lang.NoClassDefFoundError: groovy/lang/Script
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:756)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at groovy.lang.GroovyClassLoader.access$400(GroovyClassLoader.java:90)
    at groovy.lang.GroovyClassLoader$ClassCollector.createClass(GroovyClassLoader.java:700)
    at groovy.lang.GroovyClassLoader$ClassCollector.onClassNode(GroovyClassLoader.java:717)
    at groovy.lang.GroovyClassLoader$ClassCollector.call(GroovyClassLoader.java:721)
    at org.codehaus.groovy.control.CompilationUnit$3.lambda$call$0(CompilationUnit.java:806)
    at java.util.Optional.ifPresent(Optional.java:159)
    at org.codehaus.groovy.control.CompilationUnit$3.call(CompilationUnit.java:806)
    at org.codehaus.groovy.control.CompilationUnit$IPrimaryClassNodeOperation.doPhaseOperation(CompilationUnit.java:942)
    ... 25 more
Caused by: java.lang.ClassNotFoundException: groovy.lang.Script
    at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
    at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:869)
    at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:979)
    at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:967)
    at groovy.lang.GroovyClassLoader$InnerLoader.loadClass(GroovyClassLoader.java:607)
    ... 36 more

1 error

[09:49:47 WARN]:    at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:295)
[09:49:47 WARN]:    at org.codehaus.groovy.control.ErrorCollector.addException(ErrorCollector.java:143)
[09:49:47 WARN]:    at org.codehaus.groovy.control.CompilationUnit$IPrimaryClassNodeOperation.doPhaseOperation(CompilationUnit.java:976)
[09:49:47 WARN]:    at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:671)
[09:49:47 WARN]:    at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:635)
[09:49:47 WARN]:    at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:389)
[09:49:47 WARN]:    at groovy.lang.GroovyClassLoader.lambda$parseClass$3(GroovyClassLoader.java:332)
[09:49:47 WARN]:    at org.codehaus.groovy.runtime.memoize.StampedCommonCache.compute(StampedCommonCache.java:163)
[09:49:47 WARN]:    at org.codehaus.groovy.runtime.memoize.StampedCommonCache.getAndPut(StampedCommonCache.java:154)
[09:49:47 WARN]:    at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:330)
[09:49:47 WARN]:    at groovy.lang.GroovyShell.parseClass(GroovyShell.java:526)
[09:49:47 WARN]:    at groovy.lang.GroovyShell.parse(GroovyShell.java:538)
[09:49:47 WARN]:    at groovy.lang.GroovyShell.parse(GroovyShell.java:570)
[09:49:47 WARN]:    at groovy.lang.GroovyShell$parse$0.call(Unknown Source)
[09:49:47 WARN]:    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
[09:49:47 WARN]:    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
[09:49:47 WARN]:    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:148)
[09:49:47 WARN]:    at org.apache.groovy.groovysh.Interpreter.evaluate(Interpreter.groovy:76)
[09:49:47 WARN]:    at org.apache.groovy.groovysh.Evaluator$evaluate.call(Unknown Source)
[09:49:47 WARN]:    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
[09:49:47 WARN]:    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
[09:49:47 WARN]:    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:139)
[09:49:47 WARN]:    at org.apache.groovy.groovysh.Groovysh.execute(Groovysh.groovy:204)
[09:49:47 WARN]:    at uwu.smsgamer.serverscripter.groovy.shell.GrPlayerShell.execute(GrPlayerShell.java:67)
[09:49:47 WARN]:    at uwu.smsgamer.serverscripter.groovy.shell.GrPlayerShell.doExecute(GrPlayerShell.java:58)
[09:49:47 WARN]:    at uwu.smsgamer.serverscripter.shell.PlayerShell$1.run(PlayerShell.java:86)
[09:49:47 WARN]:    at java.util.TimerThread.mainLoop(Timer.java:555)
[09:49:47 WARN]:    at java.util.TimerThread.run(Timer.java:505)

我不知道为什么会发生这种情况,因为我之前放了一个Class.forName("groovy.lang.Script"),甚至创建了我自己的类来扩展该脚本类,它们都工作得很好。为什么 groovy 抱怨它自己的脚本类不存在,我不知道为什么。

请帮助

【问题讨论】:

    标签: java shell groovy


    【解决方案1】:

    只是猜测。

    如果您没有为 groovysh 指定类加载器,默认情况下它需要 Thread.currentThread().contextClassLoader

    https://github.com/groovy/groovy-core/blob/master/subprojects/groovy-groovysh/src/main/groovy/org/codehaus/groovy/tools/shell/Groovysh.groovy#L122

    所以,在执行时 currentThread().contextClassLoader 与类加载器不同,它在您的测试中成功 Class.forName("groovy.lang.Script")

    检查线程上下文类加载器可访问的 groovy 库或在创建 groovish 对象时更改类加载器。

    检查您是否拥有所有运行时的常规依赖项

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-03-02
      • 1970-01-01
      • 2014-03-12
      • 1970-01-01
      • 2021-06-23
      • 2019-01-21
      • 1970-01-01
      相关资源
      最近更新 更多