Gradle编译顺序问题:混合Java/Groovy源代码

5

我在混合Java/Groovy环境中遇到了编译顺序问题。我们使用Gradle 2.1、JDK 7和Groovy 2.3。使用Gradle插件和相同的build.gradle文件,代码可以在STS(Spring Tool Suite)中编译通过,但是在命令行上运行构建时失败了。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类,在该类中使用@Autowired注入ManagedCloseableHttpClientFactory。如下所示:

@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: error: 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"]

这里最好的方法是什么?谢谢。
2个回答

1

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


1
感谢您的回复。这项限制是否有文档记录?您知道 Groovy 开发人员是否有计划解决这个限制吗?为什么 Groovy-Eclipse 编译器可以处理它,但与 Groovy 发行版捆绑的编译器却无法处理呢?使用相同的编译器来构建 Eclipse/STS 和命令行会很好。使用 Gradle 构建的优势在于我不必单独管理 Eclipse 构建配置。但由于两种 Groovy 编译器,我时常遇到此类问题。 - user2337270
我不知道有关存根生成器限制的任何文档。对于参考编译器,已经有具体计划实现无存根联合编译,但我不知道这个功能将何时发布(最好向Groovy团队咨询)。Groovy Eclipse可能会一直使用自己的联合编译器,与Eclipse Java编译器集成。(Eclipse不使用JDK的Java编译器。) - Peter Niederwieser
谢谢你的回复,彼得。你知道是否有一种方法可以从Gradle中使用Groovy Eclipse编译器吗?这种方法会有什么严重的缺点吗?从我这个幼稚的终端用户的角度来看,我只是希望代码能像在Eclipse中一样顺畅地编译。 - user2337270
目前,Gradle只支持参考编译器。 - Peter Niederwieser

0
如果可能的话,尽量注入接口而不是具体类。由于注入发生在运行时,所以类将会完全创建,而在编译时,编译器将会识别接口是否具有所有必需的字段。
@Configuration
public class FooConfiguration {
  @Autowired
  private ClientHttpRequestFactory httpClientFactory;
...
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接