La tarea de pastoreo personalizada que accede al nivel superior falla con "El constructor ... debe ser anotado con @Inject"
Estoy tratando de crear una tarea de pastoreo reutilizable que acceda a algo desde el nivel superior. Esto funciona:
val foo = 42
tasks.register("foosimple") {
println(foo)
}
Pero usando un ejemplo modificado Desarrollar tipos de tareas de grado personalizados no:
open class Foo : DefaultTask() {
@TaskAction
fun foo() {
println(foo)
}
}
tasks.register("foo")
que falla con:
FAILURE: Build failed with an exception.
* What went wrong:
A problem occurred configuring root project 'keycloak-spi'.
> Could not create task ':foo'.
> Could not create task of type 'Foo'.
> The constructor for type Build_gradle.Foo should be annotated with @Inject.
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
¿Puede alguien echar luz sobre lo que estoy haciendo mal aquí? Si sustituyo foo()
's content with println(42)
funciona, por supuesto. Pero en realidad # para acceder a algo desde el nivel superior...
Más detalles
--stacktrace
no me fue útil:
* Exception is:
org.gradle.api.ProjectConfigurationException: A problem occurred configuring root project 'keycloak-spi'.
at org.gradle.execution.TaskNameResolver.getExistingTask(TaskNameResolver.java:116)
at org.gradle.execution.TaskNameResolver.access$000(TaskNameResolver.java:32)
at org.gradle.execution.TaskNameResolver$MultiProjectTaskSelectionResult.collect(TaskNameResolver.java:177)
at org.gradle.execution.TaskNameResolver$MultiProjectTaskSelectionResult.collectTasks(TaskNameResolver.java:169)
at org.gradle.execution.TaskNameResolver.selectWithName(TaskNameResolver.java:55)
at org.gradle.execution.TaskSelector.getSelection(TaskSelector.java:104)
at org.gradle.execution.TaskSelector.getSelection(TaskSelector.java:82)
at org.gradle.execution.commandline.CommandLineTaskParser.parseTasks(CommandLineTaskParser.java:42)
Por lo tanto, intenté añadir un @Inject
anotación en el constructor una orden, pero aparentemente, como yo, el gris no sabe @Inject
:
open class Foo @Inject constructor() : DefaultTask() {
@TaskAction
fun foo() {
println(foo)
}
}
que falla con:
Line 70: class Foo @Inject constructor() {}
^ Unresolved reference: Inject
Esta fue la única sugerencia de Intellij:
open class Foo @javax.inject.Inject constructor() : DefaultTask() {
@TaskAction
fun foo() {
println(foo)
}
}
Ahora falla con:
FAILURE: Build failed with an exception.
* What went wrong:
A problem occurred configuring root project 'keycloak-spi'.
> Could not create task ':foo'.
> Could not create task of type 'Foo'.
> 0
Así que ahora acepta el @Inject
anotación, pero todavía no funciona. Ahora me rindo y les pregunto...
Pregunta hecha hace 3 años, 4 meses, 28 días - Por devdynamox
3 Respuestas:
-
Kotlin compilador añade en secreto un parámetro generado
Foo
constructor cada vez que utiliza variables del script de construcción. Ese parámetro es una referencia al script de compilación adjunto.Como resultado, la clase de tarea no tiene constructores sin parámetro y Gradle asume que la inyección de dependencia debe comenzar. Pero no puede como constructor generado
Foo(BuildScript_XXX)
no@Inject
anotación.Si desea utilizar variables de script en su tarea debe utilizar propiedades de entrada, por ejemplo:
val foo = 42 open class Foo : DefaultTask() { @Input var fooToPrint: Int = 0 @TaskAction fun foo() { println(fooToPrint) } } tasks.register
("foo") { fooToPrint = foo } Respondida el Dec 18, 2020 a las 16:17 - por debugduke
Votos positivos: 0 | Votos negativos: 0 -
El error que estás viendo está relacionado con la forma en que estás creando tu tarea personalizada en Gradle. La anotación
@Inject
se utiliza para indicar a Dagger u otros frameworks de inyección de dependencias que deben usar ese constructor para instanciar la clase.En el caso de Gradle, no necesitas usar la anotación
@Inject
en el constructor de tu tarea personalizada. En su lugar, puedes hacer lo siguiente:kotlin open class Foo : DefaultTask() { init { group = "custom" description = "This is a custom task" } @TaskAction fun foo() { val fooValue = project.property("foo") println(fooValue) } } tasks.register("foo", Foo::class)
En este ejemplo, estamos definiendo una tarea personalizada llamada
Foo
que extiende deDefaultTask
. En el métodofoo()
, accedemos a la propiedadfoo
del proyecto utilizandoproject.property("foo")
en lugar de intentar acceder directamente a la variablefoo
.Al registrar la tarea, debes pasar la referencia a la clase
Foo::class
en lugar de solo el nombre de la tarea. De esta manera, Gradle podrá instanciar tu clase correctamente cuando se ejecute la tarea.Espero que esta solución te ayude a resolver el problema. ¡Déjame saber si tienes alguna otra duda!
Respondida el Dec 19, 2020 a las 16:14 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
El problema es que estás intentando acceder a la variable
foo
desde dentro de la tarea personalizada, pero esta variable no está definida dentro del alcance de la tarea.Para resolver este problema, puedes pasar la variable
foo
a la tarea como una entrada. Aquí tienes un ejemplo de cómo puedes hacerlo:kotlin import org.gradle.api.DefaultTask import org.gradle.api.tasks.Input import org.gradle.api.tasks.TaskAction class FooTask : DefaultTask() { @Input var foo: Int = 0 @TaskAction fun foo() { println(foo) } } tasks.register
("foo") { foo = 42 } En este ejemplo, la variable
foo
se pasa a la tarea como una entrada y se puede acceder a ella desde dentro de la tarea utilizando la propiedadfoo
.Ten en cuenta que también es necesario anotar la variable
foo
con@Input
para indicar que es una entrada de la tarea.Respondida el Dec 19, 2020 a las 16:25 - por Gemini
Votos positivos: 0 | Votos negativos: 0