繁体   English   中英

使用Java运行Javac编译的Groovy代码?

[英]Run javac compiled groovy code using java?

我有一个简单的常规文件,如下所示:

class test2 {
    public static void main(String[] args) {
        println("In groovy!!");
    }
}

我的gradle任务是将其编译到test2类文件中

如何从提示符运行此文件?

java test2 (从test2.class文件的位置)导致以下错误:无法找到或加载主类test2.class

我假设我需要在类路径中添加asm和groovy。 但是: java -cp“ groovy-all-2.3.6.jar; asm-all-3.3.1.jar” test2也不起作用(文件位于正确的位置)。

我知道对于OP来说可能有点晚了,但是:

考虑到您的常规主目录存在,错误消息:

错误:找不到或加载主类YOUR_MAINCLASS_HERE

Java命令执行groovy main (生成类的已编译groovy文件的代码)时,基本上意味着您的groovy jar 不在 classpath中

更长的答案:

让我们看看为什么这是一个简单的hello world示例。 我有一个名为main.groovy的文件,其内容如下:

class Main {
    static void main(String[] args){
            println('hello world')
    }

}

将其放在文件系统中的某个位置。 在同一目录中打开命令提示符,并确保可通过PATH访问groovy和Java。

在命令提示符下,使用groovyc编译文件,因此只需输入:

groovyc main.groovy

这将产生一个名为M ain.class的文件(由于类名而大写M)。

好的,现在我们有了适当的测试设置。 如果现在尝试仅使用java命令运行文件:

java Main 

您将收到错误消息:

错误:找不到或加载主类Main

这有点出乎意料,因为人们可能认为我们可以在不链接groovy库的情况下调用Main.class中的main,因此我们会期望像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主程序非常相似,但有一个区别: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主签名不同。

至关重要的团队成员可以澄清一下。 我希望这会给您提示。

test2.class必须在您的CLASSPATH上。 例如,如果它位于/Users/you/classes/test2.class,则/ Users / you / classes /必须位于CLASSPATH上。

由于使用Gradle进行构建,因此您也可以使用JavaExec让Gradle为您解决所有问题。 有关更多信息,请参见http://www.gradle.org/docs/current/dsl/org.gradle.api.tasks.JavaExec.html 您的build.gradle中的一个简单示例可能是这样的:

task myTask(type: JavaExec, dependsOn: 'classes') {
    main = 'test2'
    classpath = sourceSets.main.runtimeClasspath
}

希望对您有所帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM