1 Reply Latest reply: Jun 21, 2012 4:15 AM by komat RSS

Method invocation from JSF-Page failure in PrimeFaces dataTable - WeldClientProxy does not have the property

komat Newbie

Hello all,

 

well, I have a problem that's driving me rather insane for quite some time now. Basically I try to invoke a method rather than querying a property of an EJB Bean from a JSF page. And that fails because the CDI Proxy created by Weld doesn't provide that (existing) method. I'm very new to all this web-development / javaee stuff, so any comments would be of great value to me. Actually I now believe the problem lies somewhere else ... so let's get into the details.

 

Environment: I'm developing a web application based on Seam 3.1.0, JBoss AS 7.1 Final, PrimeFaces 3.1.1 (and probably some other technologies, I didn't start this project). The project is strongly based on the booking example from Seam3 - unfortunately I don't know which version exactly but it certainly predated JBoss AS 7.1 Final (probably sometime in late 2011). The example is available from the Seam 3 release files ( http://seamframework.org/Seam3/Downloads ) or github ( https://github.com/seam/examples/tree/master/booking ). I also use the EntityHome mechanism by Bernard Labno available from https://issues.jboss.org/browse/SEAMPERSIST-59 .

 

So, basically, I have an Entity Bean (Blah), I have a EJB Bean to access the Entity Bean that is extending EntityHome (BlahHome) and I want to display all Blah's from the database in a table. The relevant JSF part is:

<prime:dataTable var="blah" value="#{blahHome.blubbBlubbMethod('bleh')}">
    <prime:column>
        <f:facet name="header">
            <h:outputText value="ID"/>
        </f:facet>
        <h:outputText value="#{blah.getId}"/>
    </prime:column>
    <prime:column>
        <f:facet name="header">
            <h:outputText value="Name"/>
        </f:facet>
        <h:outputText value="#{blah.getName}"/>
    </prime:column>
    <prime:column>
        <f:facet name="header">
            <h:outputText value="Description"/>
        </f:facet>
        <h:outputText id="desc" value="#{blah.getShortenedDescription}"/>
        <prime:tooltip for="desc">
            <h:outputText value="#{blah.description}" escape="false" class="multilineTooltip"/>
        </prime:tooltip>
    </prime:column>
    <prime:column>
        <f:facet name="header">
            <h:outputText value="End"/>
        </f:facet>
        <h:outputText value="#{blah.getEnd}"/>
    </prime:column>                
</prime:dataTable>

 

The vital part is

<prime:dataTable var="blah" value="#{blahHome.blubbBlubbMethod('bleh')}">

where blubbBlubbMethod returns a List of Blah objects and binds the variable called blah to it, which is used to iterate through the list and fills the table (as far as I understand).

The blubbBlubbMethod from the BlahHome class is quite simple and has the following code:

public List<Blah> getBlahblah() {
    log.info("GETBLAHBLAH CALLED");
    List<Blah> blahblah = queries.getBlahs();
    return blahblah;
}

public List<Blah> blubbBlubbMethod(String x) {
    try {
        log.info("BLUBBBLUBBMETHOD CALLED with " + x);
        return getBlahblah();
    } catch (Exception e) {
        log.warn("BLUBBBLUBB: Catched Exception: " + e.getClass().getName() + " - " + e.getMessage());
        throw e;
    }
}

 

Now, there is no javadoc for PrimeFaces, but as far as I understand, it's primarily extending JSF constructs. The specification of dataTable for JSF ( http://javaserverfaces.java.net/nonav/docs/2.0/pdldocs/facelets/h/dataTable.html ) mentions that the "value" attribute of a dataTable must be a ValueExpression that returns an Object. Which, according to the Java EE 6 tutorial ( http://docs.oracle.com/javaee/6/tutorial/doc/bnahu.html#bnahz ) can be a method expression.

 

But what actually happens is this:

10:14:40,620 SEVERE [javax.enterprise.resource.webcontainer.jsf.application] (http--127.0.0.1-8080-1) Error Rendering View[/blahsMainPage.xhtml]: javax.el.PropertyNotFoundException: /blahsMainPage.xhtml @28,87 value="#{blahHome.blubbBlubbMethod('bleh')}": The class 'ts.test.entity.bean.BlahHome$Proxy$_$$_WeldClientProxy' does not have the property 'blubbBlubbMethod'.

So apparently the proxy class created by Weld for CDI (Dependency Injection) misses the blubbBlubbMethod. And this is the point where I am lost, because I cannot see a reason why a CDI proxy class should miss a standard method (but as I mentioned, I don't really understand these technologies on thoroughly).

 

 

But there is more to it. In general, method expressions seem to work. For example, I use

<h:outputText id="desc" value="#{blah.getShortenedDescription}"/>

and that works perfectly well.

The funny thing is, that when I make blubbBlubbMethod a property, by creating a method called getBlubbBlubbMethod(String x), it works. So apparently some part of my stack requires that the expression in the value attribute of the dataTable is a property and method expressions are not supported there. If anyone could point me to a location where this is documented or verify that this is a bug (in which part ?), I'd be immensely grateful.

 

But the best thing is: what I just posted happens when my BlahHome bean is @ConversationScoped. With @RequestScoped I get the same exception. But I also get more. Look at the following shortened stacktrace:

10:14:40,620 SEVERE [javax.enterprise.resource.webcontainer.jsf.application] (http--127.0.0.1-8080-1) Error Rendering View[/blahsMainPage.xhtml]: javax.el.PropertyNotFoundException: /blahsMainPage.xhtml @28,87 value="#{blahHome.blubbBlubbMethod('bleh')}": The class 'ts.test.entity.bean.BlahHome$Proxy$_$$_WeldClientProxy' does not have the property 'blubbBlubbMethod'.
    at com.sun.faces.facelets.el.TagValueExpression.getType(TagValueExpression.java:100) [javax.faces-2.1.7.jar:2.1.6-SNAPSHOT]
    at org.primefaces.component.datatable.DataTable.isLazy(DataTable.java:922) [primefaces-3.1.1.jar:]
    at org.primefaces.component.datatable.DataTableRenderer.encodeMarkup(DataTableRenderer.java:177) [primefaces-3.1.1.jar:]
    at org.primefaces.component.datatable.DataTableRenderer.encodeEnd(DataTableRenderer.java:103) [primefaces-3.1.1.jar:]
    at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:875) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]
    at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:312) [javax.faces-2.1.7.jar:2.1.6-SNAPSHOT]
[.....]

10:14:40,649 INFO  [ts.test.xxx.exceptioncontrol.GeneralExceptionHandler] (http--127.0.0.1-8080-1) Exception logged by seam-catch catcher: /blahsMainPage.xhtml @28,87 value="#{blahHome.blubbBlubbMethod('bleh')}": The class 'ts.test.entity.bean.BlahHome$Proxy$_$$_WeldClientProxy' does not have the property 'blubbBlubbMethod'.
10:14:41,020 INFO  [ts.test.entity.bean.BlahHome] (http--127.0.0.1-8080-1) BLAHHOME POSTCONSTRUCT
10:14:41,022 INFO  [ts.test.entity.bean.BlahHome] (http--127.0.0.1-8080-1) BLUBBBLUBBMETHOD CALLED with bleh
10:14:41,023 INFO  [ts.test.entity.bean.BlahHome] (http--127.0.0.1-8080-1) GETBLAHBLAH CALLED
10:14:41,024 WARN  [ts.test.inventory.BlahQueries] (http--127.0.0.1-8080-1) Exception during DB Query: : org.jboss.weld.context.ContextNotActiveException: WELD-001303 No active contexts for scope type javax.enterprise.context.ConversationScoped
    at org.jboss.weld.manager.BeanManagerImpl.getContext(BeanManagerImpl.java:598) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]
    at org.jboss.weld.bean.proxy.ContextBeanInstance.getInstance(ContextBeanInstance.java:71) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]
    at org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:104) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]
    at org.jboss.weld.proxies.EntityManager$ManagedPersistenceContext$1667316843$Proxy$_$$_WeldClientProxy.createNamedQuery(EntityManager$ManagedPersistenceContext$1667316843$Proxy$_$$_WeldClientProxy.java) [weld-core-1.1.5.AS71.Final.jar:]
    at ts.test.inventory.BlahQueries.getBlahs(BlahQueries.java:31) [classes:]
    at ts.test.inventory.BlahQueries$Proxy$_$$_WeldClientProxy.getBlahs(BlahQueries$Proxy$_$$_WeldClientProxy.java) [classes:]
    at ts.test.entity.bean.BlahHome.getBlahblah(BlahHome.java:91) [classes:]
    at ts.test.entity.bean.BlahHome.blubbBlubbMethod(BlahHome.java:98) [classes:]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.7.0_147-icedtea]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) [rt.jar:1.7.0_147-icedtea]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.7.0_147-icedtea]
    at java.lang.reflect.Method.invoke(Method.java:601) [rt.jar:1.7.0_147-icedtea]
[.....]

10:14:41,124 INFO  [ts.test.entity.bean.BlahHome] (http--127.0.0.1-8080-1) BLAHHOME PREDESTROY

 

There it is. blubbBlubbMethod is called actually.

Note that the POSTCONSTRUCT log text (from the method annotated with @PostConstruct) only appears after the PropertyNotFoundException arrives.

 

Now ... what to make of it ? Are there multiple passes when rendereing jsf views ? Is this a PrimeFaces fault ? Why the heck are there differences between @RequestScoped and @ConversationScoped ? How is Weld and CDI related to all of this ? Really, any hints are appreciated tremendously as I'm chewing on this problem for days now.

 

For further examination I attached all relevant classes, pages, and a more verbose stacktrace to this post - if anything more is needed, I'd be happy to supply it.

 

Thanks !

Konstantin

 

 

 

 

Some more references (it was very difficult for me to find info about the PropertyNotFoundException on the web for me):