This message was deleted.
# community-support
s
This message was deleted.
v
The main point is declare really everything what can influence task result as input, ideally by provider.
That is more for task up-to-dateness and task output cacheability. For configuration cache, you just are not allowed to do certain things at execution time like accessing the
project
or having things as properties that Gradle cannot serialize into the configuration cache.
I also basically don't understand why configuration cache require such strict requirements on tasks.
The tasks state after configuration is serialized into the CC and the deserialized from there, so some things that cannot be serialized properly just are not allowed and some things like accessing
project
is also no allowed as it might not have the state you try to query as just the tasks state is serialized in CC
With these restrictions, you can then also exeute tasks from the same project concurrently, as they are guaranteed to not influence each others configuration and so on.
a
It is possible to create a POJO class and which will contain all required data?
yeah, it should be, if it is either a Gradle managed type or it implements
java.io.Serializable
https://docs.gradle.org/current/userguide/configuration_cache.html#config_cache:not_yet_implemented:java_serialization Just make sure to annotate the task properties in the POJO with the correct task input/output types, and use
@Nested
when it’s a task property To reduce the duplication if you have lots of different specific task types, then you could create some custom task type for all your tasks, and define the POJO as a property
Copy code
abstract class MyBaseTaskType : DefaultTask() {
  @get:Nested 
  abstract val myCommonData: Property<MyCommonData>
}
and then in the plugin you can configure all tasks by type, and add the data - then it’s just done in one place
Copy code
project.tasks.withType<MyBaseTaskType>().configureEach {
  myCommonData.convention( ... )
}
v
I have for example many tasks which are run only sometimes and I doesn't need to cache their result.
You could also make them as incompatible with CC, then CC is not used if they are to be executed, but that's by far not the preferable solution
t
I basically don't need
Copy code
@get:Nested 
  abstract val myCommonData: Property<MyCommonData>
But to have Properties inside of MyCommonData like class MyCommonData { val version : Property<String> val versionCode : Property<Int> val commitHash : Property<String> } And here I don't know how to create a instance of Property
v
Just let Gradle instantiate it
ObjectFactory#newInstance
You can even make your POJO an interface
Copy code
interface MyCommonData {
   val version: Property<String>
   val versionCode: Property<Int>
   val commitHash: Property<String>
}
and then
objects.newInstance<MyCommonData>()
Then you get all the automatic Gradle decorations like implemented properties, `ExtensionAware`ness, ...
You can even mark it as
ExtensionAware
explicitly
Copy code
interface MyCommonData : ExtensionAware {
   val version: Property<String>
   val versionCode: Property<Int>
   val commitHash: Property<String>
}
Of course those properties also need the input and output annotations if you use it as
@Nested
t
And it will be also automatically serializable?
v
Should be, yes, especially when it is a managed type
But also be aware that then everyone that wants to use those tasks besides the ones you created from your plugin, or wants to configure such tasks, might have more hassle than if it simply were direct properties.
And that if in your interface things are present that only some tasks need, all tasks will have those as inputs anways.
a
check out the docs here for using
objects.newInstance()
https://docs.gradle.org/current/userguide/custom_gradle_types.html#nested_objects and here for getting an instance of ObjectFactory (because config-cache forbids using
Project.getObjects()
!) as well as other services
v
At configuration time it should be ok to use it, shouldn't it?
But if you have a full plugin class, injecting
ObjectFactory
is preferable of course.
a
At configuration time it should be ok to use it, shouldn’t it?
🤷‍♀️ config-cache is always a mystery to me. One thing works, another spits out an indecipherable error. I just always inject and use build services, and never use
Project
t
Yes. I think that access project is prohibited only in exec method.
v
yep
t
I want to basically let's task to fill all inputs itself. I will do something like this
Copy code
project.tasks.register<RemoteSignApkTask>("${variant.name}ApkRemoteSign") {
    setup(variant, gitClient, somethingElse)
}
And task will collect data that needs from theese objects. Create this POJO class instance and fill @Input field with it. I don't want to repeat setup of all inputs everytime I'm using it. And change it on several place when input requirement will change.
Wow, Gradle handle Kotlin method
fun setup()
as setter for property up, interesting.
👍 1
v
If you talk about Groovy DSL, that is not Gradle, but just plain Groovy: jdoodle.com/ia/Hml
t
No. I'm not using Groovy, just Kotlin. I had Kotlin task with method setup() and Gradle handled it as property during the automatic class enhancement.
v
Well, probably adapted to how Groovy handles it 😄