actionListener called to often
------------------------------

                 Key: TRINIDAD-1762
                 URL: https://issues.apache.org/jira/browse/TRINIDAD-1762
             Project: MyFaces Trinidad
          Issue Type: Bug
          Components: Components, Facelets
    Affects Versions: 1.2.13-core 
         Environment: Win XP,  facelets 1.1.15-jsf1.2,  Mojarra 1.2_12
            Reporter: Martin Walla


I use myfaces trinidad 1.2.13  together with facelets 1.1.15-jsf1.2 to deploy a 
war file in the JBoss 5.1.0.GA application server.
As JSF implementation the RI Mojarra (1.2_12-b01-FCS) shipped with JBoss 5.1.0 
is used.

I detected the problem that actionListener method defined on a tr:commandButton 
were called multiple times.

<tr:commandButton id="myId" textAndAccessKey="#{msg['bundlekey.mybutton']}" 
binding="#{myBean._myButton}" disabled="#{!myBean.editable}" 
partialTriggers="otherId" action="#{myBean.myAction}" 
actionListener="#{myBean.myListenerAction}" blocking="true" />


Here are my analysis:

In web.xml i have set following parameters as i found here: 
https://javaserverfaces.dev.java.net/issues/show_bug.cgi?id=1176

<context-param>
  <param-name>com.sun.faces.IS_SAVE_BINDINGS_STATE</param-name>
  <param-value>false</param-value>
</context-param>

<context-param>
  <param-name>facelets.BUILD_BEFORE_RESTORE</param-name>
  <param-value>true</param-value>
</context-param>

<context-param>
  
<param-name>facelets.RECREATE_VALUE_EXPRESSION_ON_BUILD_BEFORE_RESTORE</param-name>
  <param-value>true</param-value>
</context-param>

In the facelets class   com.sun.facelets.tag.jsf.ComponentHandler  which is the 
super class of
 org.apache.myfaces.trinidadinternal.facelets.TrinidadComponentHandler  in the 
method apply(FaceletContext ctx, UIComponent parent) there is following code.

1.) If component doesn't exist  it is created and  
com.sun.facelets.tag.jsf.ComponentHandler  line 165  it calls
this.setAttributes(ctx, c);

which in turn comes to 
com.sun.facelets.tag.jsf.ActionSourceRule$ActionListenerMapper2 method
 applyMetadata(FaceletContext ctx, Object instance)

which creates a javax.faces.event.MethodExpressionActionListener instance and 
adds it as listener to the 
org.apache.myfaces.trinidad.component.core.nav.CoreCommandButton

2.) If the component exists then com.sun.facelets.tag.jsf.ComponentHandler  
line 155  calls
recreateValueExpressions(ctx, c);

This method comes also to 
com.sun.facelets.tag.jsf.ActionSourceRule$ActionListenerMapper2 method 
applyMetadata(FaceletContext ctx, Object instance)

which creates a javax.faces.event.MethodExpressionActionListener instance and 
adds it as listener to the 
org.apache.myfaces.trinidad.component.core.nav.CoreCommandButton

And so we have a second listeners, and 3rd and 4th and so on. 

The listeners are held in an ArrayList and unfortunately there is no check if 
the added javax.faces.event.MethodExpressionActionListener represents the same 
expression.

I think it is a bug and  org.apache.myfaces.trinidad.component.UIXComponentBase 
method addFacesListener(FacesListener listener) should do something
to prevent that multiple javax.faces.event.MethodExpressionActionListener can 
be added that are representing the same EL expression which results in multiple 
calls of the same method when listeners are informed (FacesEvent broadcasted by 
org.apache.myfaces.trinidad.component.UIXComponentBase).

Callstack for 1.)

 UIXFacesBeanImpl(FacesBeanImpl).addEntry(PropertyKey, Object) line: 189 
 CoreCommandButton(UIXComponentBase).addFacesListener(FacesListener) line: 1108 
 CoreCommandButton(UIXCommand).addActionListener(ActionListener) line: 366 
 ActionSourceRule$ActionListenerMapper2.applyMetadata(FaceletContext, Object) 
line: 98 
 MetadataImpl.applyMetadata(FaceletContext, Object) line: 36 
 TrinidadComponentHandler(MetaTagHandler).setAttributes(FaceletContext, Object) 
line: 76 
 TrinidadComponentHandler(ComponentHandler).apply(FaceletContext, UIComponent) 
line: 165 
 CompositeFaceletHandler.apply(FaceletContext, UIComponent) line: 47 
 TrinidadComponentHandler(ComponentHandler).applyNextHandler(FaceletContext, 
UIComponent) line: 360 

Callstack for 2.)
 UIXFacesBeanImpl(FacesBeanImpl).addEntry(PropertyKey, Object) line: 189 
 CoreCommandButton(UIXComponentBase).addFacesListener(FacesListener) line: 1108 
 CoreCommandButton(UIXCommand).addActionListener(ActionListener) line: 366 
 ActionSourceRule$ActionListenerMapper2.applyMetadata(FaceletContext, Object) 
line: 98 
 MetadataImpl.applyMetadata(FaceletContext, Object) line: 36 
 
TrinidadComponentHandler(MetaTagHandler).recreateValueExpressions(FaceletContext,
 UIComponent) line: 87 
 TrinidadComponentHandler(ComponentHandler).apply(FaceletContext, UIComponent) 
line: 155 
 CompositeFaceletHandler.apply(FaceletContext, UIComponent) line: 47 
 TrinidadComponentHandler(ComponentHandler).applyNextHandler(FaceletContext, 
UIComponent) line: 360 


Remark:
In the meantime i found out that the improvement in facelets 1.1.15 are only in 
effect with RI Mojarra 1.2_14. I will use 1.2_12 shipped with JBoss 5.1.0.GA.
Therefore i had commented out the 3 context-parameters in web.xml and avoided 
the problem.
But nevertheless the improvements of Mojarra 1.2_14 together with facelets 
1.1.15 can't be used with myfaces trinidad 1.2.13 due to the explained problem.


-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to