Hi Gerhard, thanks for the response!

Gerhard Petracek <gerhard.petra...@gmail.com> writes:

> @codi + seam
> yes - that's possible.
> it depends on what you are using from both.
> e.g. in case of the jsf-module of codi + seam-faces you have to veto
> one of the producers for the FacesContext.

Exactly, jsf/faces modules from both.  Is vetoing done with
ClassDeactivator and writing a service-loader file?

> @ "No CreationalContext registered for EL evaluation, it is likely
> that the the expression factory has not been wrapped by the CDI
> BeanManager, which must be done to use the ELResolver from CDI":
>
> ... sounds like an as7 issue. it occurs during the rendering process
> (see e.g. UIComponentBase#encodeBegin) -> as7 has to ensure that all
> parts of cdi and jsf are up and running.

I spent some time digging around the issue going on a tip from JIRA
issue EXTVAL-140 (thanks Igor Guimaraes) - looks like it's a Weld bug.
Weld ELResolver#getValue implementation will fail unless it's nested in
a stack evaluating a Weld ValueExpression or MethodExpression.  OTOH,
ValueExpression#getValue works every time.  Even stranger is that when I
revert the project from CODI to Seam3, Weld ELResolver#getValue will
return nulls instead of throwing an exception.  Attached is a dummy
RENDER_RESPONSE PhaseListener that exhibits the bug (all the
"tryELResolver" tests fail while all the "tryValueExpression" tests
succeed).  I'll work on reporting this to Weld.  Is there any chance a
work-around could be added to ExtVal 2.0.7-SNAPSHOT? (i.e. using a
ValueExpression instead of ELResolver for BV startup)

> @enabling injection via @Advanced:
> the only known (and already fixed) issue is [1].

Is there a public maven repository where I can link 1.0.6-SNAPSHOT?

> just fyi (since you wrote "JSR-303 cross-field validation").
> annotations like @DateIs were introduced before the bv-spec. was
> released and don't use the bv-api at all (that's the reason why they
> are in a different validation module).
> you would need e.g. [2] to use the bv-api with a thin layer to allow
> bv based cross-field validation.

I was wrong about my original statement that cross-field validation
wasn't working (whereas @DateIs was working)… they're both working.

I had this question on the mailing list in March and you pointed me at
the extension then too.  I didn't have to use the extension you wrote.
I'm using the following ExtVal-BV annotation on the fields of a CDI bean
that I want cross-validation:
  @BeanValidation(modelValidation=@ModelValidation(isActive=true))
…this has been working great - am I missing something?

--
Gerald Turner   Email: gtur...@unzane.com   JID: gtur...@unzane.com
GPG: 0xFA8CD6D5  21D9 B2E8 7FE7 F19E 5F7D  4D0C 3FA0 810F FA8C D6D5
package net.concentric.icrwebtool.util;

import java.util.logging.Level;
import java.util.logging.Logger;

import javax.el.ELContext;
import javax.el.ELResolver;
import javax.el.ExpressionFactory;
import javax.el.ValueExpression;
import javax.enterprise.context.Dependent;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Produces;
import javax.faces.application.Application;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
import javax.inject.Named;

@SuppressWarnings("serial")
public class TestPhaseListener implements PhaseListener {

    private final static Logger log = Logger.getLogger(TestPhaseListener.class.getName());

    @Override
    public void beforePhase(PhaseEvent event) {
        tryTests("Before " + event.getPhaseId());
    }

    @Override
    public void afterPhase(PhaseEvent event) {
        tryTests("After " + event.getPhaseId());
    }

    @Override
    public PhaseId getPhaseId() {
        return PhaseId.RENDER_RESPONSE;
    }

    @Named("testRequestScoped")
    @Produces
    @RequestScoped
    @SuppressWarnings("unused")
    private TestObject getTestRequestScoped() {
        TestObject object = new TestObject();
        object.setMessage("Hello RequestScoped!");
        return object;
    }

    @Named("testDependent")
    @Produces
    @Dependent
    @SuppressWarnings("unused")
    private TestObject getTestDependent() {
        TestObject object = new TestObject();
        object.setMessage("Hello Dependent!");
        return object;
    }

    private void tryTests(String label) {
        log.info("tryTests: " + label);
        tryELResolver(label, "testRequestScoped");
        tryValueExpression(label, "testRequestScoped");
        tryELResolver(label, "testDependent");
        tryValueExpression(label, "testDependent");
        tryELResolver(label, "contextAwareValidatorFactory");
        tryValueExpression(label, "contextAwareValidatorFactory");
    }

    private void tryELResolver(String label, String name) {
        try {
            FacesContext facesContext = FacesContext.getCurrentInstance();
            ELResolver resolver = facesContext.getApplication().getELResolver();
            ELContext elContext = facesContext.getELContext();
            Object object = resolver.getValue(elContext, null, "contextAwareValidatorFactory");
            log.info("tryELResolver: " + label + ": Resolved " + name + ": " + object);
        }
        catch (Throwable e) {
            log.log(Level.WARNING, "tryELResolver: " + label + ": Failed to resolve " + name + ": " + e.getMessage());
        }
    }

    private void tryValueExpression(String label, String name) {
        try {
            FacesContext facesContext = FacesContext.getCurrentInstance();
            ELContext elContext = facesContext.getELContext();
            Application application = facesContext.getApplication();
            ExpressionFactory expressionFactory = application.getExpressionFactory();
            ValueExpression valueExpression = expressionFactory.createValueExpression(elContext, name, Object.class);
            Object object = valueExpression.getValue(elContext);
            log.info("tryValueExpression: " + label + ": Resolved " + name + ": " + object);
        }
        catch (Throwable e) {
            log.log(Level.WARNING, "tryValueExpression: " + label + ": Failed to resolve " + name + ": " + e.getMessage());
        }
    }

}
package net.concentric.icrwebtool.util;

import java.io.Serializable;
import java.util.logging.Logger;

import javax.annotation.PostConstruct;

@SuppressWarnings("serial")
public class TestObject implements Serializable {

    private final static Logger log = Logger.getLogger(TestObject.class.getName());

    private String message;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        log.finest("setMessage: Message set to " + message + " on " + this);
        this.message = message;
    }

    @PostConstruct
    @SuppressWarnings("unused")
    private void postConstruct() {
        log.finest("postConstruct: Constructed " + this);
    }

}

Attachment: pgpraJh5jhzN8.pgp
Description: PGP signature

Reply via email to