升级到 Gradle 2.2 后,methodMissing 不再被调用
methodMissing no longer being called on extension after upgrading to Gradle 2.2
我们的构建使用 gradle 中的自定义插件扩展,它具有动态方法。这在 gradle 2.1 中工作正常,但在 2.2 中不再调用 methodMissing 并且我得到以下异常(这是部分原因):
Caused by: org.gradle.api.internal.MissingMethodException: Could not find method common() for arguments [api] on org.gradle.api.internal.artifacts.dsl.DefaultComponentModuleMetadataHandler_Decorated@1bef1304.
at org.gradle.api.internal.AbstractDynamicObject.methodMissingException(AbstractDynamicObject.java:68)
at org.gradle.api.internal.AbstractDynamicObject.invokeMethod(AbstractDynamicObject.java:56)
at org.gradle.api.internal.CompositeDynamicObject.invokeMethod(CompositeDynamicObject.java:172)
at org.gradle.api.internal.artifacts.dsl.DefaultComponentModuleMetadataHandler_Decorated.invokeMethod(Unknown Source)
...
如何使用 gradle 2.2 让动态函数在我们的构建系统中工作?
背景:
这些动态方法有多种用途,其中之一是简化项目对其他项目的依赖(这是一个非常大的系统,有超过 80 个子项目,每个子项目可能有多个命名 API(public,内部、附加组件等))。
这是我的插件应用:
void apply(Project project) {
project.subprojects.each { subproject ->
subproject.extensions.create("modules", ModuleExtension.class ) }
}
ModuleExtension 没有除 methodMissing 之外的变量或函数:
def methodMissing(String name, args)
{
//return project dependency based on name/args. This no longer gets called in 2.2!
}
gradle 文件中的示例用法:
dependencies {
compile module.nameOfModule( "name of api" )
}
我还在 ModuleExtension 中覆盖了以下内容,只是为了看看它们是否被调用,但它们没有:
def invokeMethod(String name, args)
def propertyMissing(String name)
def propertyMissing(String name, value)
我实际上无法在 Gradle 2.2 中重现此问题。但是,这是对 Gradle 扩展的某种滥用。如果你只是想要一个全局可用的对象,我会简单地将它添加为一个额外的项目 属性。这具有不必为每个子项目创建的额外好处,因为项目从其父项目继承属性。
ext {
modules = new ModuleExtension()
}
编辑: 这是因为 Gradle 2.2 引入了对 module replacements 的新支持。 dependencies
块中的符号 modules
现在委托给 ComponentModuleMetadataHandler
而不是您的分机。您要么必须将分机重命名为 modules
以外的名称,要么使用 project.modules.nameOfModule
.
限定呼叫
我们的构建使用 gradle 中的自定义插件扩展,它具有动态方法。这在 gradle 2.1 中工作正常,但在 2.2 中不再调用 methodMissing 并且我得到以下异常(这是部分原因):
Caused by: org.gradle.api.internal.MissingMethodException: Could not find method common() for arguments [api] on org.gradle.api.internal.artifacts.dsl.DefaultComponentModuleMetadataHandler_Decorated@1bef1304.
at org.gradle.api.internal.AbstractDynamicObject.methodMissingException(AbstractDynamicObject.java:68)
at org.gradle.api.internal.AbstractDynamicObject.invokeMethod(AbstractDynamicObject.java:56)
at org.gradle.api.internal.CompositeDynamicObject.invokeMethod(CompositeDynamicObject.java:172)
at org.gradle.api.internal.artifacts.dsl.DefaultComponentModuleMetadataHandler_Decorated.invokeMethod(Unknown Source)
...
如何使用 gradle 2.2 让动态函数在我们的构建系统中工作?
背景:
这些动态方法有多种用途,其中之一是简化项目对其他项目的依赖(这是一个非常大的系统,有超过 80 个子项目,每个子项目可能有多个命名 API(public,内部、附加组件等))。
这是我的插件应用:
void apply(Project project) {
project.subprojects.each { subproject ->
subproject.extensions.create("modules", ModuleExtension.class ) }
}
ModuleExtension 没有除 methodMissing 之外的变量或函数:
def methodMissing(String name, args)
{
//return project dependency based on name/args. This no longer gets called in 2.2!
}
gradle 文件中的示例用法:
dependencies {
compile module.nameOfModule( "name of api" )
}
我还在 ModuleExtension 中覆盖了以下内容,只是为了看看它们是否被调用,但它们没有:
def invokeMethod(String name, args)
def propertyMissing(String name)
def propertyMissing(String name, value)
我实际上无法在 Gradle 2.2 中重现此问题。但是,这是对 Gradle 扩展的某种滥用。如果你只是想要一个全局可用的对象,我会简单地将它添加为一个额外的项目 属性。这具有不必为每个子项目创建的额外好处,因为项目从其父项目继承属性。
ext {
modules = new ModuleExtension()
}
编辑: 这是因为 Gradle 2.2 引入了对 module replacements 的新支持。 dependencies
块中的符号 modules
现在委托给 ComponentModuleMetadataHandler
而不是您的分机。您要么必须将分机重命名为 modules
以外的名称,要么使用 project.modules.nameOfModule
.