Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NPE in BeanValidator when the ValueReference has no base class #5155

Closed
rmartinc opened this issue Oct 19, 2022 · 1 comment · Fixed by #5156
Closed

NPE in BeanValidator when the ValueReference has no base class #5155

rmartinc opened this issue Oct 19, 2022 · 1 comment · Fixed by #5156

Comments

@rmartinc
Copy link
Contributor

Describe the bug

When the BeanValidator is called with an input that has a expression that has no base class. For example:

<h:inputText id="inputTitle" value="#{title}"/>

It throws the following NPE:

java.lang.NullPointerException
	at jakarta.faces.validator.BeanValidator.validate(BeanValidator.java:319)
	at jakarta.faces.component.UIInput.validateValue(UIInput.java:1019)
	at jakarta.faces.component.UIInput.validate(UIInput.java:825)
	at jakarta.faces.component.UIInput.executeValidate(UIInput.java:1093)
	at jakarta.faces.component.UIInput.processValidators(UIInput.java:586)
	at com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:587)
	at com.sun.faces.component.visit.PartialVisitContext.invokeVisitCallback(PartialVisitContext.java:158)
	at jakarta.faces.component.UIComponent.visitTree(UIComponent.java:1266)
	at jakarta.faces.component.UIComponent.visitTree(UIComponent.java:1278)
	at jakarta.faces.component.UIForm.visitTree(UIForm.java:344)
	at jakarta.faces.component.UIComponent.visitTree(UIComponent.java:1278)
	at jakarta.faces.component.UIComponent.visitTree(UIComponent.java:1278)
	at com.sun.faces.context.PartialViewContextImpl.processComponents(PartialViewContextImpl.java:392)
	at com.sun.faces.context.PartialViewContextImpl.processPartial(PartialViewContextImpl.java:250)
	at jakarta.faces.component.UIViewRoot.processValidators(UIViewRoot.java:1255)
	at com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:49)
	at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:72)
	at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:159)
	at jakarta.faces.webapp.FacesServlet.executeLifecyle(FacesServlet.java:691)
	at jakarta.faces.webapp.FacesServlet.service(FacesServlet.java:449)
	at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1376)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:217)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:119)
	at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:611)
	at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:550)
	at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:75)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:121)
	at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:294)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:187)
	at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:440)
	at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:144)
	at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:174)
	at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:153)
	at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:196)
	at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:88)
	at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:246)
	at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:178)
	at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:118)
	at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:96)
	at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:51)
	at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:510)
	at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:82)
	at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:83)
	at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:101)
	at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:535)
	at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:515)
	at java.base/java.lang.Thread.run(Thread.java:829)

To Reproduce

Steps to reproduce the behavior:

  1. You have a reproducer in this project of my colleague Jean François.
  2. mvn clean package
  3. sh ./target/server/bin/standalone.sh
  4. Just go to the page http://localhost:8080 fill something in the box and click add.
  5. If you prefer you can deploy in in glassfish 7 M8 (same exception). ./asadmin deploy jsf-reproducer.war

Expected behavior

The NPE should not happen.

Additional context

The valueReference.getBase() in this line is null. So I think the validator should just skip the validation as there is no base (we cannot check the value if there is no class to validate it against):

diff --git a/impl/src/main/java/jakarta/faces/validator/BeanValidator.java b/impl/src/main/java/jakarta/faces/validator/BeanValidator.java
index c5431cc8..b4696269 100644
--- a/impl/src/main/java/jakarta/faces/validator/BeanValidator.java
+++ b/impl/src/main/java/jakarta/faces/validator/BeanValidator.java
@@ -303,7 +303,7 @@ public class BeanValidator implements Validator, PartialStateHolder {
 
         ValueReference valueReference = getValueReference(context, component, valueExpression);
 
-        if (valueReference == null) {
+        if (valueReference == null || valueReference.getBase() == null) {
             return;
         }

Reading the javadoc for the value expression I think that the ValueReference can have a null base, so it's OK to return it with base null. Previously in JSF version 2.3 the validator doesn't use jakarta validation and value reference was null in this case (so it was not validated either).

I'm going to submit a PR asap.

rmartinc added a commit to rmartinc/eclipse-ee4j-mojarra that referenced this issue Oct 19, 2022
…as no base class

Signed-off-by: rmartinc <rmartinc@redhat.com>
BalusC added a commit that referenced this issue Oct 20, 2022
Fix #5155: NPE in BeanValidator when the ValueReference has no base class
@BalusC
Copy link
Contributor

BalusC commented Oct 20, 2022

Makes sense. Thank you for reporting and especially for adding the unit test!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants