]
Andreas Zschorn commented on RF-12987:
--------------------------------------
Reason is to 90% that during restore, the component is not pushed to the el context
At line 2527: ComponentSystemEventListenerAdapter.
UIComponent .getCurrentComponent(context) returns null.
---------------------------------------------------------------------------------------------------------------
wrapped = (ComponentSystemEventListener) ((listener == null)
? UIComponent
.getCurrentComponent(context)
: ((StateHolderSaver)
listener).restore(context));
NPE in UIComponent$ComponentSystemEventListenerAdapter.processEvent
when placing UITree in UIAccordionItem programmatically.
----------------------------------------------------------------------------------------------------------------------------
Key: RF-12987
URL:
https://issues.jboss.org/browse/RF-12987
Project: RichFaces
Issue Type: Bug
Security Level: Public(Everyone can see)
Components: component-tree
Affects Versions: 4.3.1
Environment: JBoss 7.1.1.Final
Mojarra 2.1.21
Reporter: Yuriy Granovskiy
Fix For: 5-Tracking
Attachments: trepanelnbar.zip
NPE appears when we place UITree into UIAccordionItem programmatically.
After postback we get:
{panel:title NPE stacktrace}
java.lang.NullPointerException
javax.faces.component.UIComponent$ComponentSystemEventListenerAdapter.processEvent(UIComponent.java:2486)
javax.faces.event.SystemEvent.processListener(SystemEvent.java:106)
com.sun.faces.application.ApplicationImpl.processListeners(ApplicationImpl.java:2168)
com.sun.faces.application.ApplicationImpl.invokeComponentListenersFor(ApplicationImpl.java:2116)
com.sun.faces.application.ApplicationImpl.publishEvent(ApplicationImpl.java:288)
com.sun.faces.application.ApplicationImpl.publishEvent(ApplicationImpl.java:246)
javax.faces.component.UIComponentBase.publishAfterViewEvents(UIComponentBase.java:2201)
javax.faces.component.UIComponentBase.doPostAddProcessing(UIComponentBase.java:1883)
javax.faces.component.UIComponentBase.setParent(UIComponentBase.java:400)
javax.faces.component.UIComponentBase$ChildrenList.add(UIComponentBase.java:2635)
javax.faces.component.UIComponentBase$ChildrenList.add(UIComponentBase.java:2607)
com.sun.faces.application.view.StateManagementStrategyImpl.restoreDynamicAdd(StateManagementStrategyImpl.java:393)
com.sun.faces.application.view.StateManagementStrategyImpl.restoreDynamicActions(StateManagementStrategyImpl.java:314)
com.sun.faces.application.view.StateManagementStrategyImpl.restoreView(StateManagementStrategyImpl.java:281)
com.sun.faces.application.StateManagerImpl.restoreView(StateManagerImpl.java:188)
com.sun.faces.application.view.ViewHandlingStrategy.restoreView(ViewHandlingStrategy.java:123)
com.sun.faces.application.view.FaceletViewHandlingStrategy.restoreView(FaceletViewHandlingStrategy.java:453)
com.sun.faces.application.view.MultiViewHandler.restoreView(MultiViewHandler.java:142)
javax.faces.application.ViewHandlerWrapper.restoreView(ViewHandlerWrapper.java:303)
com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:192)
com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:116)
com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
{panel}
Works fine if we store some another components(such as command button) in the accordion
item. But UITree causes the problem.
Here is a component class:
{code:java|title TreePanelBar.java}
@FacesComponent( value = "extended.TreePanelBar" )
@ResourceDependencies( { @ResourceDependency( library = "org.richfaces", name =
"ajax.reslib" ),
@ResourceDependency( library = "org.richfaces", name =
"base-component.reslib" ),
@ResourceDependency( library = "org.richfaces", name =
"togglePanel.js" ),
@ResourceDependency( library = "org.richfaces", name =
"accordion.js" ),
@ResourceDependency( library = "org.richfaces", name =
"AccordionItem.js" ),
@ResourceDependency( library = "org.richfaces", name =
"tree.js", target = "" ),
@ResourceDependency( library = "", name =
"richfaces-event.js", target = "" ),
@ResourceDependency( library = "org.richfaces", name =
"icons.ecss" ),
@ResourceDependency( library = "org.richfaces", name =
"accordion.ecss" ),
@ResourceDependency( library = "org.richfaces", name =
"tree.ecss", target = "" ) } )
public class TreePanelBar extends UIAccordion implements SystemEventListener,
Serializable {
private static final long serialVersionUID = -7698934343515911542L;
protected enum Properties {
node
}
public TreePanelBar() {
UIViewRoot root = getFacesContext().getViewRoot();
root.subscribeToViewEvent( PreRenderViewEvent.class, this );
}
/** {@inheritDoc} */
@Override
public void processEvent( final SystemEvent event ) throws AbortProcessingException
{
if ( getChildCount() == 0 ) {
Iterator<Object> iterator = getNode().getChildrenKeysIterator();
while ( iterator.hasNext() ) {
Object childKey = iterator.next();
DataHolderTreeNodeImpl entry = (DataHolderTreeNodeImpl)
getNode().getChild( childKey );
UIAccordionItem item = (UIAccordionItem)
getFacesContext().getApplication().createComponent( getFacesContext(),
UIAccordionItem.COMPONENT_TYPE,
"org.richfaces.AccordionItemRenderer" );
item.setId(
FacesContext.getCurrentInstance().getViewRoot().createUniqueId() );
item.setHeader( ( entry.getData() ).getLabel() );
getChildren().add( item );
// Adding a button programmatically. Works fine without tree.
UICommand button = (UICommand)
getFacesContext().getApplication().createComponent(
UICommand.COMPONENT_TYPE );
button.setId(item.getId() + "_button");
button.setValue( "Button " + item.getHeader() );
item.getChildren().add( button );
//Adding a tree programmatically. NPE in
javax.faces.component.UIComponent$ComponentSystemEventListenerAdapter.processEvent after
postback.
UITree tree = createTree( childKey, entry );
tree.setId( item.getId() + "_tree");
item.getChildren().add( tree );
}
}
}
/**
* @param childKey
* @param entry
* @return
*/
private UITree createTree( final Object childKey, final DataHolderTreeNodeImpl entry
) {
UITree tree = (UITree) getFacesContext().getApplication().createComponent(
UITree.COMPONENT_TYPE );
tree.setValue( entry );
UITreeNode uiNode = (UITreeNode)
getFacesContext().getApplication().createComponent( UITreeNode.COMPONENT_TYPE );
uiNode.setTitle( (String) entry.getKey() );
uiNode.setIconCollapsed( entry.getData().getIcon() );
uiNode.setIconExpanded( entry.getData().getIcon() );
uiNode.setId( getFacesContext().getViewRoot().createUniqueId() );
tree.getChildren().add( uiNode );
return tree;
}
/**
* @return
*/
public TreeNode getNode() {
return (TreeNode) getStateHelper().eval( Properties.node );
}
public void setNode( final TreeNode node ) {
getStateHelper().put( Properties.node, node );
}
/** {@inheritDoc} */
@Override
public boolean isListenerForSource( final Object source ) {
return true;
}
}
{code}
The exception is very similar to [
RF-11423|https://issues.jboss.org/browse/RF-11423]
The listener that is trying to get processed is for PostRenderEvent which is not
mensioned in the component code.
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: