【问题标题】:Gradle compilation ordering issue with mixed Java/Groovy source混合 Java/Groovy 源的 Gradle 编译排序问题
【发布时间】:2014-09-22 17:53:39
【问题描述】:

我在混合 Java/Groovy 环境中遇到编译顺序问题。我们正在使用 Gradle 2.1、JDK 7 和 Groovy 2.3。代码在 STS(Spring Tool Suite)中编译良好,使用 Gradle 插件和相同的 build.gradle 文件,但在命令行上运行构建时会失败。 STS 配置为使用 Groovy Eclipse 插件,如果我理解正确的话,它使用自己的编译器。所以我认为这个问题源于我们使用 Gradle 的 Groovy 插件中的 Groovy 编译器时的编译顺序问题。这是 Groovy 类:

@Component
@ToString(includeNames = true, includePackage = false)
class ManagedCloseableHttpClientFactory implements ClientHttpRequestFactory {
  @Delegate
  HttpComponentsClientHttpRequestFactory factory
...
}

ClientHttpRequestFactory 是一个 Spring 接口,由 Spring 类 HttpComponentsClientHttpRequestFactory 实现。在系统的其他地方,我们有一个用@Configuration 注解的Java 类,其中ManagedCloseableHttpClientFactory 是使用@Autowired 注入的。像这样:

@Configuration
public class FooConfiguration {
  @Autowired
  private ManagedCloseableHttpClientFactory httpClientFactory;
...
}

从命令行运行构建时,我们收到以下错误消息:/Users/xyz/source/prj/common/build/tmp/compileGroovy/groovy-java-stubs/common/web/ client/ManagedCloseableHttpClientFactory.java:10: 错误:ManagedCloseableHttpClientFactory 不是抽象的,不会覆盖 ClientHttpRequestFactory 中的抽象方法 createRequest(URI,HttpMethod)。如果我们将用@Autowired 标记的字段移动到用@Configuration 注解的Groovy 类,一切正常,但在Java 类中声明时就不行了。我猜这是一个编译排序问题。在我们的 Gradle 文件中,我们使用了 groovy 插件,并修改了源目录如下:

project.sourceSets.main.java.srcDirs = []
project.sourceSets.test.java.srcDirs = []
project.sourceSets.main.groovy.srcDirs = ["src/main/java", "src/main/groovy"]
project.sourceSets.main.resources.srcDirs  += ["config"]
project.sourceSets.test.groovy.srcDirs += ["src/test/java","src/test/groovy"]

这里最好的方法是什么?谢谢。

【问题讨论】:

    标签: spring groovy gradle


    【解决方案1】:

    Groovy 编译器的存根生成器有一些限制。我最好的猜测是你不能让 Java 调用由@Delegate 实现的 Groovy 方法。我会尝试摆脱这种特殊的 Java->Groovy 依赖或 @Delegate 的这种特殊用法(即手动实现委托)。

    【讨论】:

    • 感谢您的回复。此限制是否记录在某处?您知道 Groovy 开发人员是否有解决此限制的计划? Groovy-Eclipse 编译器如何管理它而不是与 Groovy 版本捆绑在一起的编译器?如果能够为 Eclipse/STS 和命令行使用相同的编译器,那就太好了。使用 Gradle 构建的美妙之处在于我不必单独管理 Eclipse 构建配置。但是对于两种 Groovy 编译器风格,我时不时会遇到这样的问题。
    • 我不知道存根生成器限制的任何文档。有为参考编译器实现无存根联合编译的具体计划,但我不知道该功能何时发布(最好询问 Groovy 人员)。 Groovy Eclipse 可能总是有自己的联合编译器,它与 Eclipse Java 编译器集成。 (Eclipse 不使用 JDK Java 编译器。)
    • 感谢您的回复彼得。你知道是否有办法使用 Gradle 中的 Groovy Eclipse 编译器?这种方法会有任何严重的缺点吗?从我天真的最终用户的角度来看,我只是希望代码能够像在 Eclipse 中一样顺利编译。
    • 目前Gradle只支持参考编译器。
    【解决方案2】:

    如果可能,注入接口而不是具体类。由于注入发生在运行时,因此类将被完整创建,并且在编译时编译器会将接口识别为具有所有必需的字段。

    @Configuration
    public class FooConfiguration {
      @Autowired
      private ClientHttpRequestFactory httpClientFactory;
    ...
    }
    

    【讨论】:

      猜你喜欢
      • 2017-09-11
      • 2014-04-05
      • 2011-01-13
      • 1970-01-01
      • 1970-01-01
      • 2016-09-07
      • 1970-01-01
      • 1970-01-01
      • 2014-12-22
      相关资源
      最近更新 更多