Describe the bug
When a Qute template is injected via constructor injection, the template cannot be rendered in RestAssured tests and it throws a NullPointer exception.
Using field injection it works fine.
This only happens in the test, when running the application regularly, it works without problems.
Expected behavior
The test should work using constructor injection.
Actual behavior
A NullPointerException is thrown.
2020-07-30 12:05:31,837 ERROR [io.qua.ver.htt.run.QuarkusErrorHandler] (executor-thread-1) HTTP Request to /journey failed, error id: 8672cd43-da4f-48b0-a508-9e05fe5edb6d-1: org.jboss.resteasy.spi.UnhandledException: java.lang.NullPointerException
at org.jboss.resteasy.core.ExceptionHandler.handleException(ExceptionHandler.java:381)
at org.jboss.resteasy.core.SynchronousDispatcher.writeException(SynchronousDispatcher.java:216)
at org.jboss.resteasy.core.SynchronousDispatcher.writeResponse(SynchronousDispatcher.java:610)
....
Caused by: java.lang.NullPointerException
at io.quarkus.qute.runtime.TemplateProducer$InjectableTemplateInstanceImpl.renderAsync(TemplateProducer.java:153)
at io.quarkus.resteasy.qute.runtime.TemplateResponseFilter.filter(TemplateResponseFilter.java:53)
at org.jboss.resteasy.core.interception.jaxrs.ContainerResponseContextImpl.filter(ContainerResponseContextImpl.java:361)
at org.jboss.resteasy.core.ServerResponseWriter.executeFilters(ServerResponseWriter.java:252)
at org.jboss.resteasy.core.ServerResponseWriter.writeNomapResponse(ServerResponseWriter.java:101)
at org.jboss.resteasy.core.ServerResponseWriter.writeNomapResponse(ServerResponseWriter.java:74)
at org.jboss.resteasy.core.SynchronousDispatcher.writeResponse(SynchronousDispatcher.java:590)
... 18 more
More precisely the tempate() function in TemplateProducer.java:153 returns the null value as TemplateProducer.java:167 getAttribute(TemplateInstance.SELECTED_VARIANT) returns null.
I looked a little into it and it seemed the variants field of the TemplateProducer stays empty.
To Reproduce
Steps to reproduce the behavior:
@Path("/test")
public class TestController {
private final Template test;
@Inject
public TestController(Template test) {
this.test = test;
}
@GET
public TemplateInstance showTest() {
return this.test.data("someValue", "someValue");
}
@Test
void test_canBeRendered() {
given()
.when()
.get("/test")
.then()
.statusCode(HttpStatus.SC_OK);
}
Environment (please complete the following information):
uname -a or ver: Linux manjaro 5.7.9-1-MANJARO #1 SMP PREEMPT Thu Jul 16 08:20:05 UTC 2020 x86_64 GNU/Linuxjava -version: java version "14.0.2" 2020-07-14mvnw --version or gradlew --version): Apache Maven 3.6.3/cc @mkouba, @manovotn
/cc @mkouba
@ChFlick Can you see a similar warning in the log?
WARN [io.qua.qut.run.TemplateProducer] (executor-thread-1) Parameter name not present - using the method name as the template name instead ...
It seems that the class is not compiled with -parameters and therefore quarkus is not able to derive the template name from the injection point.
You can either compile your class with -parameters or make use of @io.quarkus.qute.api.ResourcePath, i.e.
@Inject
public TestController(@ResourcePath("test") Template test) {
this.test = test;
}
In Maven you can also use -Dmaven.compiler.parameters=true (maven-compiler-plugin 3.6.2+).
Yes that was it. I got a similar warning.
Using either -parameters or the @io.quarkus.qute.api.ResourcePath annotation resolved the issue.
Thank you very much.