I'm working on a Gradle (Groovy, not Kotlin) library 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:
ClassA.gradle
class ClassA extends com.external.plugin.TaskA {}
ClassB.gradle
import com.fasterxml.jackson.databind.ObjectMapper
class ClassB extends ClassA {}
...with no restrictions on where things need to be, just that it works. 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.
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 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.
buildSrc/src/main/groovy/ClassA.gradle exists and is the same as above.
buildSrc/build.gradle
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.
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.