gpt4 book ai didi

java - 访问在应用的外部脚本中的 buildscript block 中定义的类路径依赖项

转载 作者:搜寻专家 更新时间:2023-11-01 03:00:11 29 4
gpt4 key购买 nike

我最初的目标是能够使用 buildscript 中定义的类路径依赖项在 build.gradle , 在导入到 build.gradle 的脚本中使用 apply from: .但是,由于无法解析类,因此外部脚本无法编译。研究这个问题后,我发现逻辑需要复制,所以我想我会提取buildscript到一个单独的文件中。然后我就可以在 build.gradle 中应用它并且也在外部脚本内部。

我什至没有成功应用来自 build.gradle 的外部构建脚本文件,更不用说从外部脚本应用它了。我尝试了多种方法,但无论我尝试什么,似乎总是以两个问题之一结束:来自 gradle.properties 的属性之一。无法使用,或者找不到插件(即使已经定义了类路径依赖项)。

目前我的 gradle/buildscript.gradle文件如下所示:

buildscript {
repositories {
maven { url "http://some.url.com" }
}

dependencies {
classpath "my.gradle.plugin:gradle-plugin:1.0.0"
classpath "my.library:my-library:$libraryVersion"
}
}
libraryVersion已在 gradle.properties 中定义.我的 build.gradle如下:
buildscript {
apply from: "gradle/buildscript.gradle"
}

apply plugin: 'my.gradle.plugin.PluginClass'

当我这样做时,gradle 提示它找不到 ID 为 my.gradle.plugin.PluginClass 的插件.我尝试删除引号,我也尝试 project.plugin.apply(...)使用带引号和不带引号的插件的 FQN;这两种情况都会导致 gradle 出错,并显示一条消息说它找不到属性 my在根项目上。

我也试过:
buildscript {
apply from: "gradle/buildscript.gradle", to: buildscript
}

apply plugin: 'my.gradle.PluginClass'

但这会导致另一个错误,其中 gradle 提示它无法解析 libraryVersiongradle/buildscript.gradle .所以我然后尝试了这个:
buildscript {
ext.libraryVersion = "1.0.1"

repositories {
maven { url "http://some.url.com" }
}

dependencies {
classpath "my.gradle.plugin:gradle-plugin:1.0.0"
classpath "my.library:my-library:$libraryVersion"
}
}

这导致了另一个错误,其中 gradle 说没有这样的属性 extbuildscript .我明白这是因为现在确实没有“项目”可言,因为 buildscript单独编译。然后我换了我的 buildscript阻止 build.gradle回到:
buildscript {
apply from: "gradle/buildscript.gradle"
}

现在我没有收到 ext错误,但我仍然收到错误消息,说它找不到具有指定 ID 的插件。

我无法硬编码 libraryVersionbuildscript ,因为我需要它作为 build.gradle 中的编译时依赖项我宁愿不必在两个地方维护它。

这非常令人困惑和沮丧,因为以下 buildscript block 本身在 build.gradle 中工作正常:
buildscript {
ext.libraryVersion = "1.0.1"

repositories {
maven { url "http://some.url.com" }
}

dependencies {
classpath "my.gradle.plugin:gradle-plugin:1.0.0"
classpath "my.library:my-library:$libraryVersion"
}
}

apply plugin: 'my-plugin-id' //No need to use FQN

dependencies {
compile "my.library:library-version:$libraryVersion"
}

我试图拆分 buildscript 的原因阻塞是因为我有一个文件 other.gradle有一些使用来自 my.library 的类的自定义任务:
import my.library.SomeThing

task customTask(type: DefaultTask) {
//does something with SomeThing
}

但是当我离开时 buildscript阻止 build.gradle并像这样应用另一个文件:
buildscript {
ext.libraryVersion = "1.0.1"

repositories {
maven { url "http://some.url.com" }
}

dependencies {
classpath "my.gradle.plugin:gradle-plugin:1.0.0"
classpath "my.library:my-library:$libraryVersion"
}
}

apply plugin: 'my-plugin-id' //No need to use FQN

dependencies {
compile "my.library:my-library:$libraryVersion"
}

apply from: 'gradle/other.gradle'

我从 gradle 收到一个错误,说它无法解析类 my.library.SomeThing .我想我可以解决这个问题并通过使用一个通用的 buildscript 来避免重复。然后我可以在 build.gradle 中应用的文件和 other.gradle .

我在 buildSrc 里面创建了一个自定义插件以我想要的方式配置项目,结果却以更复杂的方式失败并导致相同的结果。根本原因是相同的:无法将类路径依赖项暴露给外部脚本。

是否有关于此类行为的综合文档?这一切都违反了最小惊喜原则。我期待一个 buildscript正在使用的 block build.gradle当我将它移动到另一个文件时“正常工作”。
apply的语义关于 buildscript block 不清楚。另外, buildscript的语义当它出现在外部文件中时,它本身也不清楚 - 行为有明显的变化,特别是在插件和外部属性方面。

处理这个问题的最佳方法是什么?

最佳答案

这有点啰嗦,但也有解决方案。我能够在不使用单独的 buildscript 的情况下解决此问题文件,但解决方法是令人难以置信的hackish。我认为您无法跨外部脚本共享 buildscript 依赖项是一个主要缺点。

问题是没有语义一致性,因为行为似乎取决于您决定如何组织/模块化您的构建逻辑。如果这是一个已知问题,则需要在文档中的某个地方特别指出 - 我能够找到提到这种令人惊讶的行为的唯一方法是来自 gradle 自己的论坛或 StackOverflow。我不认为期望在单个文件中与离散的构建逻辑单元一起工作的构建在这些离散单元被拆分到多个文件时也能工作是不合理的。只要语义一致,构建逻辑不应因您决定组织文件的方式而异。

我知道可能存在技术限制,但是仅仅因为您将逻辑从一个文件移动到另一个文件而导致构建中断是抽象泄漏,因为现在我需要知道这样做的细节和复杂性,超出了人们应该合理预期的范围.我什至不介意这是否被明确和特别地提出,以及解决语义差异的解决方案/变通办法。但是,当前有关组织构建逻辑的文档没有提到这些警告;它只记录了幸福的道路。

/咆哮

所以这是解决方案。我通过使用扩展保存了对类本身的引用:

import my.library.SomeThing
import my.library.SomeOtherThing

buildscript {
ext.libraryVersion = "1.0.1"

repositories {
maven { url "http://some.url.com" }
}

dependencies {
classpath "my.gradle.plugin:gradle-plugin:1.0.0"
classpath "my.library:my-library:$libraryVersion"
}
}

apply plugin: 'my-plugin-id' //No need to use FQN

ext.SomeThing = SomeThing
ext.SomeOtherThing = SomeOtherThing

dependencies {
compile "my.library:my-library:$libraryVersion"
}

apply from: 'gradle/other.gradle'

然后在 other.gradle :
// Necessary; you can't just use ext.SomeThing in the task later because 
// it is available at compile-time, but apparently not at runtime. Although
// it does work if you use project.ext.SomeThing. However, I just found this
// to be more convenient.
def SomeThing = ext.SomeThing
def SomeOtherThing = ext.SomeOtherThing

task someTask(type: DefaultTask) {
// You have to use def; you cannot use the actual type because
// it is not available at compile-time. Also, since you only
// have a class object, you cannot use "new" directly; you have to
// create a new instance by calling newInstance() on the class object
def someThing = SomeThing.newInstance(...)

// If you are calling static methods you can invoke them directly
// on the class object. Again, you have to use def if the return
// type is something defined within my-library.
def foo = SomeOtherThing.staticMethod(...)
}

关于java - 访问在应用的外部脚本中的 buildscript block 中定义的类路径依赖项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37058780/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com