在 JRE 容器之前有 Spring Gradle 依赖容器会导致编译错误

Having Spring Gradle dependency container before JRE container results in compilation errors

我正在将 Java 项目从 Ant 转换为 Gradle。我们团队选择的 IDE 是 Eclipse。我已经为 Eclipse 安装了 Spring Gradle 插件,应用了 Gradle 项目性质并启用了依赖管理。结果是一些编译错误。

出现编译错误是因为 Gradle 依赖容器在 eclipse 类路径中的 JRE 容器之前。类路径上的一些 jar 包含 类,应该来自 rt.jar(它们与我们的代码不兼容,可能是旧版本)。

当禁用依赖管理时gradle 依赖出现在 JRE 容器之后,它编译没有错误。这也与我使用 Eclipse/Maven/m2e 一致,其中 Maven 依赖容器位于 eclipse 中的 JRE 容器之后。

这是插件的默认行为吗(将 gradle 容器放在 JRE 之前)?有办法改变吗?

我尝试在 build.gradle 中使用 eclipse 挂钩(whenMerged 和 withXml)来执行此操作,但这些挂钩似乎在 gradle 依赖项被容器条目替换之前执行。

对顺序有一些控制,但对您来说可能不够精确。右键单击项目和 select 'Properties >> Gradle'.

然后select排序选项之一,如'Alphabetically by Path'。更改此选项后执行 "Gradle >> Refresh All".

如果你选"As returned by BuildScript",我收集的一定是你有的。顺序将相反(JRE 之前的 Gradle)。这里有一个难题,即构建脚本实际上并不 return "gradle dependencies" 容器(仅其内容),因此构建脚本并未真正定义顺序。

不幸的是,您可能有理由选择该选项并且对容器内的依赖项进行排序实际上可能不是您的可行解决方案。

如果是这样,您可能还可以尝试第二种方法。

当您导入项目时,您会在 "Import Options" 下使用导入向导 "Run After"。您可能会尝试使用那里指定的任务在导入结束时修改 .classpath 文件(它也会在刷新时执行)。

最后……最后一个建议。你试过BuildShip了吗?也许它更适合您的项目。

这是我交换容器的代码。由于几个原因,它可能有点冗长。 1. 我是 Groovy 的新手,背景是 Java。 2.Gradle对自己和团队都是新手,想清楚它是干什么的

// Swap the order of the JRE and classpathcontainer
// https://issuetracker.springsource.com/browse/STS-4332
task afterEclipseImport(description: "Post processing after project generation", group: "IDE") {
    doLast {
        def cp = new XmlParser().parse(file(".classpath"))
        def container
        def cons = cp.classpathentry.findAll { it.@kind == "con" }
        cons.find {
            if (it.@path.equals("org.springsource.ide.eclipse.gradle.classpathcontainer")) {
                println "found Gradle dependency container"
                container = it
            } else if (it.@path.contains("JRE_CONTAINER")) {
                if (container == null) {
                    println "found JRE container before Gradle dependency container, nothing to do"
                    // Return true to end the loop (return by itself is not enough)
                    return true
                }
                println "found JRE container, swap with Gradle dependency container"
                container.replaceNode(it)
                it.replaceNode(container)
                // Return true to end the loop (return by itself is not enough)
                return true
            }
            return false
        }
        def builder = new StreamingMarkupBuilder()
        builder.encoding = "UTF-8"
        file(".classpath").withWriter {writer ->
             writer << builder.bind { mkp.xmlDeclaration() }
             def printer = new XmlNodePrinter(new PrintWriter(writer))
             // println cp
             printer.print(cp)
        }
    }
}