How to redefine a task method from gradle script?

In order to temporarily workaround a limitation on the jacoco plugin (without patching it), I’d like to redefine a method this way

  task jacocoReport(type: JacocoReport) {

doFirst {

def oldMethod = it.metaClass.getClassDirs

it.metaClass.getClassDirs = { ->

oldMethod.filter {! (’.jar’)}



I’m afraid this kind of meta programming somewhat hurts some gradle internals, cause it seems that the original method is redefined with my closure, but then it fails complaining
  org.gradle.api.internal.MissingMethodException: Could not find method structure() for arguments [{name=TEST}, org.ajoberstar.gradle.jacoco.tasks.JacocoReport$_generate_closure1_closure8@13da177] on task ':TEST:jacocoReport'.

at org.gradle.api.internal.AbstractDynamicObject.methodMissingException(

at org.gradle.api.internal.AbstractDynamicObject.invokeMethod(

at org.gradle.api.internal.CompositeDynamicObject.invokeMethod(

at org.ajoberstar.gradle.jacoco.tasks.JacocoReport_Decorated.invokeMethod(Unknown Source)

at org.ajoberstar.gradle.jacoco.tasks.JacocoReport$_generate_closure1.doCall(JacocoReport.groovy:62)

at org.ajoberstar.gradle.jacoco.tasks.JacocoReport$_generate_closure1.doCall(JacocoReport.groovy)

at org.gradle.api.internal.project.ant.BasicAntBuilder.doInvokeMethod(

at org.gradle.api.internal.project.DefaultAntBuilder.super$3$invokeMethod(DefaultAntBuilder.groovy)

at org.gradle.api.internal.project.DefaultAntBuilder.invokeMethod(DefaultAntBuilder.groovy:37)

at org.ajoberstar.gradle.jacoco.tasks.JacocoReport.generate(JacocoReport.groovy:58)

at org.gradle.api.internal.BeanDynamicObject$MetaClassAdapter.invokeMethod(

at org.gradle.api.internal.BeanDynamicObject.invokeMethod(  

The exception is saying that a different method is missing. I’m not seeing the relationship.

The problem is that the issue arises if I use the instance metaClass in order to replace the original method with my closure. The missing method is actually an element available for jacoco report ant task. It’'s called at ( , and its body/closure should invoke my closure at Moreover the method I have replaced is annotated as a task input… so I suspect my change somewhat breaks the gradle ANT builder (but maybe I’m wrong).

So I’d like to know if there’s a better way to replace a task method (provided that mine is clearly a workaround).

Cheers Davide

I replied to you some days ago, but I missed leaving directly a comment… any idea on why the issue arises if I use the instance metaClass in order to replace the original method with my closure?

There is no supported way to replace a task method, and monkey patching is always risky business. You might be better off forking (or contributing to) the plugin.