diff --git a/extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/QuteProcessor.java b/extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/QuteProcessor.java index 54a1022511e6b..c551f46da2c6b 100644 --- a/extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/QuteProcessor.java +++ b/extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/QuteProcessor.java @@ -1783,7 +1783,7 @@ private static BeanInfo findBean(Expression expression, IndexView index, Expression.Part firstPart = expression.getParts().get(0); if (firstPart.isVirtualMethod()) { incorrectExpressions.produce(new IncorrectExpressionBuildItem(expression.toOriginalString(), - "The inject: namespace must be followed by a bean name", + "The " + expression.getNamespace() + ": namespace must be followed by a bean name", expression.getOrigin())); return null; } @@ -1793,8 +1793,12 @@ private static BeanInfo findBean(Expression expression, IndexView index, return bean; } else { // User is injecting a non-existing bean - incorrectExpressions.produce(new IncorrectExpressionBuildItem(expression.toOriginalString(), - beanName, null, expression.getOrigin())); + if (!expression.toOriginalString().endsWith("or(null)")) { + // Fail unless a safe expression + // Note that foo.val?? becomes foo.val.or(null) during parsing + incorrectExpressions.produce(new IncorrectExpressionBuildItem(expression.toOriginalString(), + beanName, null, expression.getOrigin())); + } return null; } } diff --git a/extensions/qute/deployment/src/test/java/io/quarkus/qute/deployment/inject/NamedBeanNotFoundSafeTest.java b/extensions/qute/deployment/src/test/java/io/quarkus/qute/deployment/inject/NamedBeanNotFoundSafeTest.java new file mode 100644 index 0000000000000..2192e9f86da88 --- /dev/null +++ b/extensions/qute/deployment/src/test/java/io/quarkus/qute/deployment/inject/NamedBeanNotFoundSafeTest.java @@ -0,0 +1,29 @@ +package io.quarkus.qute.deployment.inject; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import jakarta.inject.Inject; + +import org.jboss.shrinkwrap.api.asset.StringAsset; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.qute.Template; +import io.quarkus.test.QuarkusUnitTest; + +public class NamedBeanNotFoundSafeTest { + + @RegisterExtension + static final QuarkusUnitTest config = new QuarkusUnitTest() + .withApplicationRoot(root -> root + .addAsResource(new StringAsset("{cdi:ping.val??}"), "templates/ping.html")); + + @Inject + Template ping; + + @Test + public void testTemplate() { + assertEquals("", ping.render()); + } + +}