我知道这对于 OP 来说可能有点晚了,但是:
鉴于您的 groovy main 存在,错误消息:
错误:无法找到或加载主类 YOUR_MAINCLASS_HERE
从 java 命令在执行 groovy main(生成类的已编译 groovy 文件)基本上意味着您的 groovy jar 是不在 类路径中。
更长的答案:
让我们看看为什么这是一个简单的 hello world 示例。我有一个名为 main.groovy 的文件,其内容如下:
class Main {
static void main(String[] args){
println('hello world')
}
}
把它放在你的文件系统中的某个地方。在同一目录中打开命令提示符并确保可以通过 PATH 访问 groovy 和 java。
在命令提示符下,用groovyc编译文件,所以只需输入:
groovyc main.groovy
这将生成一个名为 Main.class 的文件(由于类名,M 大写)。
好的,现在我们有了适当的测试设置。如果您现在尝试仅使用 java 命令运行该文件:
java Main
您将收到错误消息:
错误:无法找到或加载主类 Main
这有点出乎意料,因为我们可以认为我们可以在 Main.class 中调用 main 而无需链接 groovy 库,所以我们会期待 ClassNotFoundException 这样的异常。
相反,在你的类路径中使用 groovy 再试一次。我将您的 groovy 安装目录称为 GROOVY_HOME。最后运行 hello world Main 类,我们可以输入:
java -cp ".:/$GROOVY_HOME/lib/*" 主要
在类 unix 系统上产生预期的输出(在 Windows 上,您需要用分号替换冒号,变量访问类似于 %GROOVY_HOME%)。
原因很简单:Groovy 为 groovy 主要方法生成的签名与 Java 规范所要求的签名不同。因此,您只能在 CLASSPATH 上使用 groovy 调用 groovy main - 这是完全有道理的!
您可以自己检查一下。现在试试这个命令:
javap Main.class
这将使您快速分析“Main.class”类的字节码和当前接口。一直以来,您都会看到与此输出类似的内容:
Compiled from "main.groovy"
public class Main implements groovy.lang.GroovyObject {
public static transient boolean __$stMC;
public Main();
public static void main(java.lang.String...);
protected groovy.lang.MetaClass $getStaticMetaClass();
public groovy.lang.MetaClass getMetaClass();
public void setMetaClass(groovy.lang.MetaClass);
public java.lang.Object invokeMethod(java.lang.String, java.lang.Object);
public java.lang.Object getProperty(java.lang.String);
public void setProperty(java.lang.String, java.lang.Object);
}
感兴趣的是第 5 行:
public static void main(java.lang.String...);
这似乎与普通的 java main 非常相似,但有一个区别:groovyc 使用了 java.lang.String 省略号(如三个点所示)而不是 java.lang.String[]。
所以这可能是原因。我不太确定,因为通常如果 java 可以找到类而不是方法签名,它会给你一个适当的错误输出。例如,尝试:
java java.lang.Integer
这显然不是一个主要的方法。 Java 正确地看到了这一点:
Error: Main method not found in class java.lang.Integer, please define the main method as:
public static void main(String[] args)
or a JavaFX application class must extend javafx.application.Application
我也不确定,在类加载期间 groovy 做了什么来理解这种主要签名(或者说这种字节码),但是如果你将它与普通的 java hello world javap 输出进行比较,你会得到
public class JMain {
public JMain();
public static void main(java.lang.String[]);
}
它有一个不同的和正常的 java 主签名。
也许关键的 groovy 团队中的某个人可以澄清一下。
我希望这会给你一个提示。