Eclipse 插件与配置缓存不兼容。

Eclipse 插件会生成 Eclipse IDE 所使用的文件,从而使得项目可以导入到 Eclipse 中(File - Import…​ - Existing Projects into Workspace)。

eclipse 插件应用于 WarEar 项目时,eclipse-wtp 会自动应用。对于实用项目(即其他 web 项目使用的 Java 项目),您需要显式应用 eclipse-wtp 插件。

eclipse 插件具体生成什么取决于使用了哪些其他插件

表 1. Eclipse 插件行为
插件 描述

生成最小的 .project 文件。

Java

将 Java 配置添加到 .project。生成 .classpath 和 JDT 设置文件。

Groovy

将 Groovy 配置添加到 .project 文件。

Scala

将 Scala 支持添加到 .project.classpath 文件。

War

将 web 应用支持添加到 .project 文件。

Ear

将 ear 应用支持添加到 .project 文件。

eclipse-wtp 插件生成所有 WTP 设置文件并增强 .project 文件。如果应用了 JavaWar 插件,.classpath 将被扩展以获得该实用库或 web 应用项目的正确打包结构。

两个 Eclipse 插件都支持自定义,并提供了一套标准化的钩子,用于添加和移除生成文件中的内容。

用法

要使用 Eclipse 或 Eclipse WTP 插件,请在您的构建脚本中包含以下一行:

build.gradle.kts
plugins {
    eclipse
}
build.gradle
plugins {
    id 'eclipse'
}
build.gradle.kts
plugins {
    `eclipse-wtp`
}
build.gradle
plugins {
    id 'eclipse-wtp'
}

注意: 在内部,eclipse-wtp 插件也会应用 eclipse 插件,因此您无需同时应用两者。

这两个 Eclipse 插件都会向您的项目添加许多任务。您将主要使用 eclipsecleanEclipse 任务。

任务

Eclipse 插件会向项目添加如下所示的任务。

Eclipse 插件任务

eclipse任务

依赖于:所有 Eclipse 配置文件生成任务

生成所有 Eclipse 配置文件

cleanEclipse删除

依赖于:所有 Eclipse 配置文件清理任务

移除所有 Eclipse 配置文件

cleanEclipseProject删除

移除 .project 文件。

cleanEclipseClasspath删除

移除 .classpath 文件。

cleanEclipseJdt删除

移除 .settings/org.eclipse.jdt.core.prefs 文件。

eclipseProject生成 Eclipse 项目

生成 .project 文件。

eclipseClasspath生成 Eclipse Classpath

生成 .classpath 文件。

eclipseJdt生成 Eclipse Jdt

生成 .settings/org.eclipse.jdt.core.prefs 文件。

Eclipse WTP 插件 — 附加任务

cleanEclipseWtpComponent删除

移除 .settings/org.eclipse.wst.common.component 文件。

cleanEclipseWtpFacet删除

移除 .settings/org.eclipse.wst.common.project.facet.core.xml 文件。

eclipseWtpComponent生成 Eclipse WTP Component

生成 .settings/org.eclipse.wst.common.component 文件。

eclipseWtpFacet生成 Eclipse WTP Facet

生成 .settings/org.eclipse.wst.common.project.facet.core.xml 文件。

配置

表 2. Eclipse 插件配置
模型 参考名称 描述

EclipseModel

eclipse

顶层元素,用于以 DSL 友好的方式配置 Eclipse 插件。

EclipseProject

eclipse.project

允许配置项目信息

EclipseClasspath

eclipse.classpath

允许配置 classpath 信息。

EclipseJdt

eclipse.jdt

允许配置 JDT 信息(源/目标 Java 兼容性)。

EclipseWtpComponent

eclipse.wtp.component

仅当应用了 eclipse-wtp 插件时,允许配置 WTP component 信息。

EclipseWtpFacet

eclipse.wtp.facet

仅当应用了 eclipse-wtp 插件时,允许配置 WTP facet 信息。

自定义生成的文件

Eclipse 插件允许您自定义生成的元数据文件。这些插件提供了一个 DSL,用于配置模拟项目 Eclipse 视图的模型对象。然后,这些模型对象与现有的 Eclipse XML 元数据合并,最终生成新的元数据。这些模型对象提供了较低级别的钩子,用于在与模型配置合并之前和之后处理表示文件内容的领域对象。它们还提供了一个非常低级别的钩子,用于在持久化之前直接处理原始 XML 以进行调整,适用于 Eclipse 和 Eclipse WTP 插件未建模的微调和配置。

合并

现有 Eclipse 文件中作为生成内容目标的部分将被修改或覆盖,具体取决于特定部分。其余部分将保持不变。

通过完全重写禁用合并

要完全重写现有的 Eclipse 文件,请将清理任务与其对应的生成任务一起执行,例如“gradle cleanEclipse eclipse”(按此顺序)。如果您想将其设为默认行为,请将“tasks.eclipse.dependsOn(cleanEclipse)”添加到您的构建脚本中。这样就不需要显式执行清理任务了。

这种策略也可以用于插件将生成的单个文件。例如,可以使用“gradle cleanEclipseClasspath eclipseClasspath”对“.classpath”文件进行此操作。

挂钩到生成生命周期

Eclipse 插件提供了建模由 Gradle 生成的 Eclipse 文件部分的模型对象。生成生命周期如下:

  1. 读取文件;如果文件不存在,则使用 Gradle 提供的默认版本

  2. 使用表示现有文件的领域对象执行 beforeMerged 钩子

  3. 现有内容与从 Gradle 构建推断或在 eclipse DSL 中显式定义的配置合并

  4. 使用表示要持久化的文件内容的领域对象执行 whenMerged 钩子

  5. 使用将要持久化的 XML 的原始表示执行 withXml 钩子

  6. 最终的 XML 被持久化

高级配置钩子

以下列表涵盖了用于每种 Eclipse 模型类型的领域对象

EclipseProject
EclipseClasspath
EclipseWtpComponent
EclipseWtpFacet
EclipseJdt
  • beforeMerged { Jdt arg -> …​ }

  • whenMerged { Jdt arg -> …​ }

  • withProperties { arg -> } 参数类型 ⇒ java.util.Properties

部分覆盖现有内容

完全覆盖会导致所有现有内容被丢弃,从而丢失直接在 IDE 中进行的任何更改。或者,beforeMerged 钩子可以只覆盖现有内容的某些部分。以下示例从 Classpath 领域对象中移除所有现有依赖项

build.gradle.kts
import org.gradle.plugins.ide.eclipse.model.Classpath

eclipse.classpath.file {
    beforeMerged(Action<Classpath> {
        entries.removeAll { entry -> entry.kind == "lib" || entry.kind == "var" }
    })
}
build.gradle
eclipse.classpath.file {
    beforeMerged { classpath ->
        classpath.entries.removeAll { entry -> entry.kind == 'lib' || entry.kind == 'var' }
    }
}

生成的 .classpath 文件将只包含 Gradle 生成的依赖项条目,而不包含原始文件中可能存在的任何其他依赖项条目。(对于依赖项条目,这也是默认行为。).classpath 文件的其他部分将保持原样或被合并。对于 .project 文件中的 natures,也可以做同样的事情

build.gradle.kts
import org.gradle.plugins.ide.eclipse.model.Project

eclipse.project.file.beforeMerged(Action<Project> {
    natures.clear()
})
build.gradle
eclipse.project.file.beforeMerged { project ->
    project.natures.clear()
}

修改完全填充的领域对象

whenMerged 钩子允许操作完全填充的领域对象。这通常是自定义 Eclipse 文件的首选方式。以下是如何导出 Eclipse 项目的所有依赖项

build.gradle.kts
import org.gradle.plugins.ide.eclipse.model.AbstractClasspathEntry
import org.gradle.plugins.ide.eclipse.model.Classpath

eclipse.classpath.file {
    whenMerged(Action<Classpath> { ->
        entries.filter { entry -> entry.kind == "lib" }
            .forEach { (it as AbstractClasspathEntry).isExported = false }
    })
}
build.gradle
eclipse.classpath.file {
    whenMerged { classpath ->
        classpath.entries.findAll { entry -> entry.kind == 'lib' }*.exported = false
    }
}

修改 XML 表示

withXml 钩子允许在文件写入磁盘之前操作内存中的 XML 表示。尽管 Groovy 的 XML 支持和 Kotlin 的扩展函数弥补了很多不足,但这种方法不如操作领域对象方便。作为回报,您可以完全控制生成的文件,包括领域对象未建模的部分。

示例 6. 自定义 XML
build.gradle.kts
import org.w3c.dom.Element

eclipse.wtp.facet.file.withXml(Action<XmlProvider> {
    fun Element.firstElement(predicate: Element.() -> Boolean) =
        childNodes
            .run { (0 until length).map(::item) }
            .filterIsInstance<Element>()
            .first { it.predicate() }

    asElement()
        .firstElement { tagName === "fixed" && getAttribute("facet") == "jst.java" }
        .setAttribute("facet", "jst2.java")
})
build.gradle
eclipse.wtp.facet.file.withXml { provider ->
    provider.asNode().fixed.find { it.@facet == 'jst.java' }.@facet = 'jst2.java'
}

分离测试 classpath 条目

Eclipse 为每个项目只定义一个 classpath,这意味着 Gradle 项目的映射方式存在限制。Eclipse 4.8 引入了测试源的概念。此特性允许 Eclipse 插件更好地分离测试源和非测试源。

Eclipse classpath 由 classpath 条目组成:源目录、jar 文件、项目依赖项等。每个 classpath 条目可以有一个 classpath 属性列表,其中属性是字符串键值对。有两个与测试源相关的 classpath 属性:testwithout_test_code,它们的值都可以是 truefalse

如果源目录具有 test=true classpath 属性,则其内容被视为测试源。测试源可以访问非测试源,但非测试源无法访问测试源。类似地,测试源只能引用具有 test=true classpath 属性的 jar 文件中的类。对于项目依赖项,如果存在 test=true 属性,则目标项目中的类对于测试源是可见的。如果存在 without_test_code=false 属性,则目标项目的测试源也可访问。默认情况下,测试代码不可用(这可以视为隐式具有 without_test_code=true)。

生成 Eclipse classpath 时,以下规则适用于测试属性声明

  • 如果源集和依赖配置的名称包含 'test' 子字符串(不区分大小写),则将其归类为测试。

  • 由 JVM 测试套件插件定义的所有源集和依赖配置都归类为测试。

  • 如果容器源集是测试源集,则源目录具有 test=true classpath 属性。

  • 如果 Jar 文件和项目依赖项仅存在于测试依赖配置中,则它们具有 test=true 属性。

  • 如果目标项目应用了 java-test-fixtures 插件,则项目依赖项具有 without_test_sources=false 属性。

您可以自定义测试源集和配置

build.gradle.kts
eclipse {
    classpath {
        testSourceSets = testSourceSets.get() + setOf(integTest)
        testConfigurations = testConfigurations.get() + setOf(functional)
    }
}
build.gradle
eclipse {
    classpath {
        testSourceSets = testSourceSets.get() + [sourceSets.integTest]
        testConfigurations = testConfigurations.get() + [configurations.functional]
    }
}
在这种情况下,考虑从手动定义额外的测试源集迁移到使用 JVM Test Suite Plugin

您还可以通过 containsTestFixtures 属性自定义项目是否应向其上游项目依赖项公开测试源。

build.gradle.kts
eclipse {
    classpath {
        containsTestFixtures = true
    }
}
build.gradle
eclipse {
    classpath {
        containsTestFixtures = true
    }
}

请注意,此配置也适用于 Buildship 项目的 classpath。