Estoy tratando de seguir la documentación del complemento personalizado de Gradle para crear un complemento que se pueda configurar.
Mi código de complemento:
interface MyExtension { var myValue: Property<String> } class MyPlugin : Plugin<Project> { override fun apply(project: Project) { val extension = project.extensions.create<MyExtension>("myExt") } } en build.gradle.kts :
plugins { `java-library` } apply<MyPlugin>() the<MyExtension>().myValue.set("some-value")Ejecutar esto dará
Build file '<snip>/build.gradle.kts' line: 6 java.lang.NullPointerException (no error message) Resulta que the<MyExtension>().myValue es null , por lo que la llamada al set falla. ¿Cómo hago esto correctamente? ¿Me perdí algo en la documentación, o simplemente está mal?
La documentación no está mal. Las propiedades pueden ser administradas por usted o por Gradle. Para esto último, se deben cumplir ciertas condiciones.
Si desea estar completamente a cargo, puede instanciar cualquier variable que declare usted mismo. Por ejemplo, para declarar una propiedad en una extensión que es una interfaz, podría verse así:
override fun apply(project: Project) { val extension = project.extensions.create("myExt", MyExtension::class.java) extension.myValue = project.objects.property(String::class.java) }O podría instanciarlo directamente en la extensión convirtiéndolo en una clase en su lugar:
open class MessageExtension(objects: ObjectFactory) { val myValue: Property<String> = objects.property(String::class.java) }Sin embargo, no se supone que un campo de propiedad tenga un setter ya que la propiedad en sí tiene tanto un setter como un getter. Por lo tanto, generalmente debe evitar el primer acercamiento y eliminar el colocador en el segundo.
Consulteaquí para obtener más ejemplos sobre cómo administrar las propiedades usted mismo.
Para ayudarlo a reducir el código repetitivo, Gradle puede instanciar las propiedades por usted con lo que se denomina propiedades administradas . Para usarlos, la propiedad no debe tener un definidor, y el captador debe ser abstracto (que implícitamente está en una interfaz). Entonces, podría volver a su primer ejemplo y arreglarlo cambiando var a val :
interface MyExtension { val myValue: Property<String> // val (getter only) }Ahora Gradle creará una instancia del campo por usted. Lo mismo funciona para las clases abstractas.
Obtenga más información sobre las propiedades administradas en la documentación aquí .