【问题标题】:How to compile mixed java groovy project with AST transformations?如何使用 AST 转换编译混合 java groovy 项目?
【发布时间】:2016-09-07 09:38:59
【问题描述】:

当我尝试使用带有以下类的 groovy-eclipse 编译器编译我的 project 时:

 import groovy.transform.builder.Builder

// @author: m on 10.05.16 22:15.
@Builder
class F {

   int a

}

public class B {

   int a;

public static void main(String[] args) {
    F.FBuilder builder = F.builder();

    F build = builder.a(1).build();
  }
}

出现以下错误:

[INFO] Using Groovy-Eclipse compiler to compile both Java and Groovy files
[INFO] -------------------------------------------------------------
[ERROR] COMPILATION ERROR : 
[INFO] -------------------------------------------------------------
[ERROR] /Users/m/git_repo/mix/src/main/java/B.java:[7,1] 1. ERROR in /Users/m/git_repo/mix/src/main/java/B.java (at line 7)
    F.FBuilder builder = F.builder();
    ^^^^^^^^^^
F.FBuilder cannot be resolved to a type

[ERROR] /Users/m/git_repo/mix/src/main/java/B.java:[7,24] 2. ERROR in /Users/m/git_repo/mix/src/main/java/B.java (at line 7)
    F.FBuilder builder = F.builder();
                           ^^^^^^^
The method builder() is undefined for the type F
[ERROR] Found 2 errors and 0 warnings.

如何解决?请帮忙

【问题讨论】:

    标签: java groovy transformation abstract-syntax-tree groovy-eclipse


    【解决方案1】:

    您可能只想使用def 关键字代替F.FBuilder。使用联合编译时(java和groovy混合在同一个源文件夹中),groovy文件映射到Eclipse/JDT的Java模型中。然而,这种映射发生在应用许多 AST 转换之前,因此 Java 看不到像 @Builder 添加这样的其他类型和方法。

    【讨论】:

      【解决方案2】:

      如果您不介意将 Java 和 Groovy 类拆分为不同的 Maven 模块,我强烈建议您这样做。

      好处是您永远不会遇到联合编译问题,您将清楚地了解什么依赖于什么(从 Java 模块中使用 Groovy 模块,您需要向它添加 Maven 依赖项),Groovy AST 将从 Java 类中可见,并且通过不在同一模块中混合语言来保持理智。

      我在 GitHub 上创建了一个简单的 java-groovy-maven-test 项目来展示如何做到这一点。

      基本上,您创建了两个模块,一个只包含您的 Java 类(我的项目中的test-java),另一个包含 Groovy 类(test-groovy)。

      两者都在同一个父 Maven 模块下。

      这比尝试在同一个模块中同时编译 Groovy/Java 效果要好得多。

      有关如何构建和测试项目的说明在 README 页面上。

      【讨论】:

        【解决方案3】:

        尝试使用maven-antrun-plugin

        <plugin>
            <artifactId>maven-antrun-plugin</artifactId>
            <executions>
                <execution>
                    <id>compile</id>
                    <phase>compile</phase>
                    <configuration>
                        <tasks>
                            <mkdir dir="${basedir}/src/main/groovy"/>
                            <taskdef name="groovyc"
                                classname="org.codehaus.groovy.ant.Groovyc">
                                <classpath refid="maven.compile.classpath"/>
                            </taskdef>
                            <mkdir dir="${project.build.outputDirectory}"/>
                            <groovyc destdir="${project.build.outputDirectory}"
                                srcdir="${basedir}/src/main/groovy/" listfiles="true">
                                <classpath refid="maven.compile.classpath"/>
                            </groovyc>
                        </tasks>
                    </configuration>
                    <goals>
                        <goal>run</goal>
                    </goals>
                </execution>
                <execution>
                    <id>test-compile</id>
                    <phase>test-compile</phase>
                    <configuration>
                        <tasks>
                            <mkdir dir="${basedir}/src/test/groovy"/>
                            <taskdef name="groovyc"
                                classname="org.codehaus.groovy.ant.Groovyc">
                                <classpath refid="maven.test.classpath"/>
                            </taskdef>
                            <mkdir dir="${project.build.testOutputDirectory}"/>
                            <groovyc destdir="${project.build.testOutputDirectory}"
                                srcdir="${basedir}/src/test/groovy/" listfiles="true">
                                <classpath refid="maven.test.classpath"/>
                            </groovyc>
                        </tasks>
                    </configuration>
                    <goals>
                        <goal>run</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        

        【讨论】:

        • 谢谢。实际上,我可以使用 gmaven-plus,但我希望能够使用 intellij idea 中指定的 groovy-eclipse(或其他支持的)编译器编译代码。有可能吗?
        • 我在我的项目中使用上述配置,并且 IntelliJ 支持非常棒。
        • 好吧,我的意思是,当目标文件夹为空时,我希望能够使用 Build/Compile 'B.java' 菜单选项编译 B 类。它适用于您的情况吗?
        • 如果您在构建器中使用 SimpleStrategy,IntelliJ 可以编译它(否则它看不到 FBuilder 类型)......但是当使用 Maven 构建时,Groovy 类在 Java 中不可见,不幸的是。 .. 所以如果我是你,我会坚持使用 groovy-eclipse 编译器插件。
        • 我仍然无法编译 @Builder(builderStrategy = SimpleStrategy) class F { int a int d } public class B { public static void main(String[] args) { F f = new F( ).setA(1).setD(2); } } 信息:Using Groovy-Eclipse to compile Java & Groovy sources Information:12.05.16 22:35 - Compilation completed with 1 error and 0 warning in 2s 636ms /Users/m/git_repo/mix/src/main/java/B .java 错误:(7,-1)Groovy-Eclipse:无法在原始类型 void 上调用 setD(int)
        【解决方案4】:

        如果需要交叉编译,Java 文件需要与 Groovy 文件放在 groovy 目录下。

        【讨论】:

        猜你喜欢
        • 2011-01-13
        • 1970-01-01
        • 1970-01-01
        • 2021-10-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-18
        相关资源
        最近更新 更多