Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Named object not found

Tags:

java

jsf

jsf-2

cdi

I created a new validator:

package com.example.jsf.validator;

import com.example.components.LoginFormValue;
import com.example.ejb.SecurityEjb;
import java.io.Serializable;
import javax.ejb.EJB;
import javax.enterprise.context.ApplicationScoped;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;
import javax.inject.Named;

/**
 * Validator for {@code login-form} component.
 *
 * @author steve
 */
@Named
@ApplicationScoped
public class LoginValidator implements Validator, Serializable
{
    @Override
    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException
    {
        if (value == null)
        {
            return;
        }

        LoginFormValue loginFormValue = (LoginFormValue) value;
        if (securityEjb.checkCredentials(loginFormValue.getEmailAddress(), loginFormValue.getPassword())) {
            return;
        }

        throw new ValidatorException(new FacesMessage("Incorrect email address/password"));
    }

    @EJB
    private SecurityEjb securityEjb;
}

But when I try to use it:

<my:login-form emailAddress="#{loginBean.emailAddress}"
               rememberMe="#{loginBean.rememberMe}"
               actionListener="#{loginBean.submit()}"
               recoverPasswordOutcome="recover-password"
               registerOutcome="signup">
    <f:validator validatorId="#{loginValidator}"/>
</my:login-form>

I get this exception displayed when I load the page:

javax.faces.FacesException: Expression Error: Named Object: com.example.jsf.validator.LoginValidator@31888ef8 not found.

The offending line of code is:

com.sun.faces.application.ApplicationImpl.createValidator(ApplicationImpl.java:1593)

Why can JSF actually resolve the validator bean class yet not be able to instantiate it? Every other validator in my app is a Named ApplicationScoped bean and they all work just fine. I reference them all using <f:validator validatorId="{myValidatorBean}"/>.

I'm using GlassFish 3.1.2.

like image 519
Steve Avatar asked Dec 26 '22 23:12

Steve


1 Answers

The <f:validator validatorId> must refer the ID of the validator, not the concrete validator instance. The ID of the validator is exactly the one which you've specified as @FacesValidator value or as <validator-id> when using the faces-config.xml approach. E.g.

@FacesValidator("myValidator")

which is then to be referenced as

<f:validator validatorId="myValidator" />

Any EL expression in validatorId would during view build time be resolved to a String identifying the validator ID. So when passing a concrete Validator instance, it would only end up its toString() value like com.example.MyValidator@hashcode being passed as validator ID which does after all obviously not exist, as the exception message is trying to tell you:

javax.faces.FacesException: Expression Error: Named Object: com.example.jsf.validator.LoginValidator@31888ef8 not found.

You should be using <f:validator binding> or <h:inputText validator> instead. It can take a concrete instance.

<f:validator binding="#{myValidator}" />

That it doesn't work when been passed to a composite component is a different problem. You namely didn't specify the for attribute at all, so it won't be applied on any of the UIInput components inside the composite. I think the following question/answer will be fully applicable in order to solve that: How to specify a validator for an input component inside a composite component?

like image 125
BalusC Avatar answered Jan 10 '23 06:01

BalusC