Actually it is untypical to set the complex object directly.
Due to several reasons.
Currently your @Input is not used at all anyway.
If you run your task a second time without change using --info, you will see
Task ‘:myTask’ is not up-to-date because:
Task has not declared any outputs despite executing actions.
If you add an actual output or use outputs.upToDateWhen { true } and try to run the task, you will see
Cannot fingerprint input property ‘server’: value ‘extension ‘myx’ property ‘server’’ cannot be serialized.
This is the cause, because @Input annotation is only valid on serializable classes, because the serialized state is then used as part of the fingerprint calculation.
Unless you actually want to enable a user to set the whole server object, the usual way is to instead wire the single properties, especially if the complex object is only meant to enable hierarchical DSL syntax.
This also allows to use additional instances of the task without the need to instantiate a Server object, but by simply setting the single properties.
If you really want to use Server as @Input you have to make it serializable.
So this would be the more typical setup:
apply plugin: MyPlugin
abstract class Server {
abstract Property<String> getUrl()
}
abstract class MyExtension {
@Nested
abstract Server getServer()
// for DSL
def server(Action action) {
action.execute(server)
}
}
abstract class MyTask extends DefaultTask {
@Input
abstract Property<String> getServerUrl()
@TaskAction
def run() {
println "MyTask.run - ${serverUrl.get()}"
}
}
class MyPlugin implements Plugin<Project> {
void apply(Project project) {
MyExtension myExtension = project.extensions.create("myx", MyExtension)
project.tasks.register("myTask", MyTask) { task ->
task.serverUrl.set(myExtension.server.url)
}
}
}
// test config
myx {
server {
url = 'url from config'
}
}