Is it possible to make a doubly-inherited custom task?

I’m working on a library (Groovy-based, not Kotlin) using a bunch of external libraries, and we have a case where we want to implement double-inheritance in our code off of a custom Task provided by an external library. (For reference, that library is specifically the MarkLogic DataHub, and we’re extending RunFlowTask, but I’ve generalized a bit for this example. There are a few restrictions that introduces, but I’m fairly certain all of them can be worked around.)

What I want is the following:


class ClassA extends com.external.plugin.TaskA {}


import com.fasterxml.jackson.databind.ObjectMapper

class ClassB extends ClassA {}

Worth noting that we have a bunch of examples like ClassA that work on their own, I just need to extend ClassA again.

I’ve detailed a few attempts I made to get this to work below; any feedback on what I did wrong with any of them is more than welcome, or if there’s any advice on an entirely new way to build things, that’s totally appreciated as well.

First attempt:

apply from: './ClassA'
apply from: './ClassB'

‘unable to resolve class ClassA’ in ClassB.gradle, which makes enough sense given what I know about how Gradle compilation works. I tried replacing the definition for class ClassB... with println ClassB just to see, and that printed without an issue. Made me think that ClassA needed to be compiled in advance, so I’m pretty sure there’s nothing I’m doing wrong here, it just won’t work.

Second attempt:

buildSrc/src/main/groovy/ClassA.gradle exists and is the same as above.


import com.fasterxml.jackson.databind.ObjectMapper

buildscript {
    repositories { }
    dependencies {
        classpath fileTree(dir: '/path/to/dependencies', include: '*.jar') // includes jackson

println ObjectMapper

The println worked, but I get:

/path/to/src/main/groovy/ClassA.groovy: 1: unable to resolve class com.fasterxml.jackson.databind.ObjectMapper
 @ line 1, column 1.
   import com.fasterxml.jackson.databind.ObjectMapper

…and the same thing if I duplicate the buildscript block into the ClassA submodule, or if I remove the import from the ClassA submodule. My question for this is is there anything I’m doing wrong with the imports? Seems like this should work and the imports should just work, but they’re not.

Third attempt:

Sparing a few code examples here: I got everything very close to working with copying buildSrc into an includeBuild folder, and ClassA is accessible as a TaskReference in the top-level project, but I don’t know how to to actually extend ClassA from there.

gradle.includedBuild('subbuild').task(':ClassA') => org.gradle.composite.internal.IncludedBuildTaskReference
gradle.includedBuild('subbuild').task(':UPMCRunFlowTask').resolveTask() => Task with path ':ClassA' not found in project ':subbuild'.

My question for this is is there a way to dig back to the class reference so it’s actually extendable? I tried digging into setting up an include './subbuild' subproject and ran into similar issues.

Any help/advice is welcome - thanks!

Answer was on the second attempt. In build.gradle, it needed to be:

repositories {}
dependencies {
    implementation fileTree(dir: '/path/to/deps', include: ['*.jar'])

…and nothing needed to be in the sub-files.