[Logo] Enterprise Client Community
  [Search] Search   [Recent Topics] Recent Topics   [Members]  Member Listing   [Groups] Back to home page 
[Register] Register / 
[Login] Login 
Strange behavior of EL- Resolver when using ComponentTags  XML
Forum Index -> Development
Author Message
unger

Power User

Joined: 22/07/2008 05:19:28
Messages: 261
Offline

Hello,

building an UI within a pane using ComponentTag(s) shows me a mystery:

Code:
 else if (component instanceof Lookup) {
 				Lookup lookup = (Lookup) component;
 				CCLookup c = new CCLookup(lookup);
 				if (c != null) {
 					BaseComponent newComponent[] = c.createInputComponent(lookup, getOwningDispatcher());
 					parent.getChildren().add(newComponent[0]);
 					parent.getChildren().add(newComponent[1]);
 					ccValueMap.put(CCUTIL.replaceSpace(lookup.getId()), c);
 				}
 


Look inside createInputComponent:
Code:
 public BaseComponent[] createInputComponent(Lookup field, IDispatcher dispatcher) {
 			LABELComponentTag ltag = new LABELComponentTag();
 			COMBOBOXComponentTag tag = new COMBOBOXComponentTag();
 			BaseComponent[] b = null;
 			try {
 				ltag.setText(field.getLabelText());
 				ltag.setWidth(field.getWidthLabel());
 				ltag.setX(field.getX());
 				ltag.setY(field.getY());
 
 				Integer i0 = new Integer(field.getX());
 				Integer i1 = new Integer(field.getWidthLabel());
 				Integer i2 = i1 + i0;
 				tag.setWidth(field.getWidthField());
 				tag.setX(i2.toString());
 				tag.setY(field.getY());
 				tag.setFlush("true");
 
 				String expression = "#{d.AnalyticClientMBean.ccValue." + CCUTIL.replaceSpace(field.getId()) + ".vv}";
 				expression = dispatcher.updateExpression(expression);
 				tag.setValidvaluesbinding(expression);
 
 				expression = "#{d.AnalyticClientMBean.ccValue." + CCUTIL.replaceSpace(field.getId()) + ".value}";
 				expression = dispatcher.updateExpression(expression);
 				tag.setValue(expression);
 				b = new BaseComponent[] { ltag.createBaseComponent(), tag.createBaseComponent() };
 			} catch (Throwable t) {
 				logger.error(t.getStackTrace());
 			}
 			return b;
 		}
 


The class Code:
public static class CCLookup extends CCValue  implements IValidValueUpdateable
holds a value with getter and setter.

Inside base class CCValue is a
Code:
protected abstract Object getValue();


What happen, if the instance will be updated? Yes there are setters to be used in the setter-phase. But the EL-Resolver does not recognize it.

javax.servlet.ServletException: Servlet execution threw an exception
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:313)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at com.schott.indit.passntAdmin.utils.LoginFilter.doFilter(LoginFilter.java:46)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.eclnt.jsfserver.util.ThreadingFilter.doFilter(ThreadingFilter.java:226)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.eclnt.jsfserver.util.CompressionFilter.doFilter(CompressionFilter.java:33)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:12
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.Error: java.lang.Error: javax.el.PropertyNotFoundException: Property 'value' not writable on type java.lang.Object
at org.eclnt.jsfserver.util.StackedValueExpression.setValue(StackedValueExpression.java:281)
at org.eclnt.jsfserver.util.StackedValueExpression.setValue(StackedValueExpression.java:243)
at org.eclnt.jsfserver.util.ExpressionManagerV.setValue(ExpressionManagerV.java:51)
at org.eclnt.jsfserver.elements.BaseComponent$SetValueExec.execute(BaseComponent.java:75)
at org.eclnt.jsfserver.elements.BaseComponent.processUpdates(BaseComponent.java:849)
at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1081)
at org.eclnt.jsfserver.elements.BaseComponent.processUpdates(BaseComponent.java:853)
at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1081)
at org.eclnt.jsfserver.elements.BaseComponent.processUpdates(BaseComponent.java:853)
at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1081)
at org.eclnt.jsfserver.elements.BaseComponent.processUpdates(BaseComponent.java:853)
at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1081)
at org.eclnt.jsfserver.elements.BaseComponent.processUpdates(BaseComponent.java:853)
at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1081)
at org.eclnt.jsfserver.elements.BaseComponent.processUpdates(BaseComponent.java:853)
at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1081)
at org.eclnt.jsfserver.elements.BaseComponent.processUpdates(BaseComponent.java:853)
at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1081)
at org.eclnt.jsfserver.elements.BaseComponent.processUpdates(BaseComponent.java:853)
at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1081)
at org.eclnt.jsfserver.elements.BaseComponent.processUpdates(BaseComponent.java:853)
at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1081)
at org.eclnt.jsfserver.elements.BaseComponent.processUpdates(BaseComponent.java:853)
at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1081)
at org.eclnt.jsfserver.elements.BaseComponent.processUpdates(BaseComponent.java:853)
at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1081)
at javax.faces.component.UIForm.processUpdates(UIForm.java:260)
at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1081)
at javax.faces.component.UIViewRoot.processUpdates(UIViewRoot.java:72
at com.sun.faces.lifecycle.UpdateModelValuesPhase.execute(UpdateModelValuesPhase.java:7
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:11
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:265)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
... 20 more
Caused by: java.lang.Error: javax.el.PropertyNotFoundException: Property 'value' not writable on type java.lang.Object
at org.eclnt.jsfserver.util.CCELResolver.setValue(CCELResolver.java:244)
at org.eclnt.jsfserver.util.StackedValueExpression.setValueExecute(StackedValueExpression.java:396)
at org.eclnt.jsfserver.util.StackedValueExpression.setValue(StackedValueExpression.java:250)
... 53 more
Caused by: javax.el.PropertyNotFoundException: Property 'value' not writable on type java.lang.Object
at javax.el.BeanELResolver$BeanProperty.write(BeanELResolver.java:247)
at javax.el.BeanELResolver$BeanProperty.access$100(BeanELResolver.java:209)
at javax.el.BeanELResolver.setValue(BeanELResolver.java:106)
at javax.el.CompositeELResolver.setValue(CompositeELResolver.java:6
at com.sun.faces.el.FacesCompositeELResolver.setValue(FacesCompositeELResolver.java:100)
at org.eclnt.jsfserver.util.CCELResolver.setValue(CCELResolver.java:230)
... 55 more

When replacing the abstract Object Method inside CCValue with
Code:
 private Object value;
 
 		public Object getValue() {
 			return value;
 		}
 
 		public void setValue(Object value) {
 			this.value = value;
 		}
 

the program works. The setter in the base class will be found.

Even if the Map ccValueMap is defined as HashMap<String, CCValue> there should be a dynamically type check (Java behavior) and the setter of CCLookup should be used.

I could not build a simple demo to reproduce the problem. It works in the simple case.

Any hints?

Joachim
unger

Power User

Joined: 22/07/2008 05:19:28
Messages: 261
Offline

Additionally You will find the calling stack below, just before invoking the method setValue (..) inside CCValue:

Code:
 Daemon Thread [http-50000-2] (Suspended (breakpoint at line 1270 in AnalyticClientMBean$CCValue))	
 	AnalyticClientMBean$CCLookup(AnalyticClientMBean$CCValue).setValue(Object) line: 1270	
 	NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]	
 	NativeMethodAccessorImpl.invoke(Object, Object[]) line: not available	
 	DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: not available	
 	Method.invoke(Object, Object...) line: not available	
 	BeanELResolver.setValue(ELContext, Object, Object, Object) line: 108	
 	FacesCompositeELResolver(CompositeELResolver).setValue(ELContext, Object, Object, Object) line: 68	
 	FacesCompositeELResolver.setValue(ELContext, Object, Object, Object) line: 100	
 	CCELResolver.setValue(ELContext, Object, Object, Object) line: 230	
 	StackedValueExpression.setValueExecute(ELContext, Object, boolean) line: 396	
 	StackedValueExpression.setValue(ELContext, Object, boolean) line: 250	
 	StackedValueExpression.setValue(ELContext, Object) line: 243	
 	ExpressionManagerV.setValue(FacesContext, Object, Object) line: 51	
 	BaseComponent$SetValueExec.execute() line: 75	
 	COMBOBOXComponent(BaseComponent).processUpdates(FacesContext) line: 849	
 	PAINTAREAComponent(UIComponentBase).processUpdates(FacesContext) line: 1081	
 	PAINTAREAComponent(BaseComponent).processUpdates(FacesContext) line: 853	
 	ROWComponent(UIComponentBase).processUpdates(FacesContext) line: 1081	
 	ROWComponent(BaseComponent).processUpdates(FacesContext) line: 853	
 	TABBEDPANETABComponent(UIComponentBase).processUpdates(FacesContext) line: 1081	
 	TABBEDPANETABComponent(BaseComponent).processUpdates(FacesContext) line: 853	
 	TABBEDPANEComponent(UIComponentBase).processUpdates(FacesContext) line: 1081	
 	TABBEDPANEComponent(BaseComponent).processUpdates(FacesContext) line: 853	
 	ROWComponent(UIComponentBase).processUpdates(FacesContext) line: 1081	
 	ROWComponent(BaseComponent).processUpdates(FacesContext) line: 853	
 	PANEComponent(UIComponentBase).processUpdates(FacesContext) line: 1081	
 	PANEComponent(BaseComponent).processUpdates(FacesContext) line: 853	
 	ROWComponent(UIComponentBase).processUpdates(FacesContext) line: 1081	
 	ROWComponent(BaseComponent).processUpdates(FacesContext) line: 853	
 	PANEComponent(UIComponentBase).processUpdates(FacesContext) line: 1081	
 	PANEComponent(BaseComponent).processUpdates(FacesContext) line: 853	
 	ROWComponent(UIComponentBase).processUpdates(FacesContext) line: 1081	
 	ROWComponent(BaseComponent).processUpdates(FacesContext) line: 853	
 	ROWBODYPANEComponent(UIComponentBase).processUpdates(FacesContext) line: 1081	
 	ROWBODYPANEComponent(BaseComponent).processUpdates(FacesContext) line: 853	
 	UINamingContainer(UIComponentBase).processUpdates(FacesContext) line: 1081	
 	HtmlForm(UIForm).processUpdates(FacesContext) line: 260	
 	UIViewRoot(UIComponentBase).processUpdates(FacesContext) line: 1081	
 	UIViewRoot.processUpdates(FacesContext) line: 728	
 	UpdateModelValuesPhase.execute(FacesContext) line: 78	
 	UpdateModelValuesPhase(Phase).doPhase(FacesContext, Lifecycle, ListIterator<PhaseListener>) line: 100	
 	LifecycleImpl.execute(FacesContext) line: 118	
 	FacesServlet.service(ServletRequest, ServletResponse) line: 265	
 	ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 290	
 	ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 206	
 	LoginFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 46	
 	ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 235	
 	ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 206	
 	ThreadingFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 226	
 	ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 235	
 	ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 206	
 	CompressionFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 33	
 	ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 235	
 	ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 206	
 	StandardWrapperValve.invoke(Request, Response) line: 233	
 	StandardContextValve.invoke(Request, Response) line: 191	
 	StandardHostValve.invoke(Request, Response) line: 128	
 	ErrorReportValve.invoke(Request, Response) line: 102	
 	StandardEngineValve.invoke(Request, Response) line: 109	
 	CoyoteAdapter.service(Request, Response) line: 286	
 	Http11Processor.process(Socket) line: 845	
 	Http11Protocol$Http11ConnectionHandler.process(Socket) line: 583	
 	JIoEndpoint$Worker.run() line: 447	
 	Thread.run() line: not available	
 
unger

Power User

Joined: 22/07/2008 05:19:28
Messages: 261
Offline

Here is a demo. Change the field's value, then press the button.

Code:
 package managedbeans;
 
 import java.util.HashMap;
 
 import javax.faces.event.ActionEvent;
 
 public class Page3Bean {
 	private HashMap<String, HasAValue> fieldWithValueMap = new HashMap<String, HasAValue> ();
 	private FieldWithValue fieldWithValue = new FieldWithValue ();
 	{
 		fieldWithValueMap.put ("S", fieldWithValue);
 	}
 	private String field = "Outer Field";
 
 	public Page3Bean () {
 	}
 
 	public Page3Bean (Dispatcher dispatcher) {
 	}
 
 	public static abstract class HasAValue {
 		// private Object value;
 		//		public void setValue (Object value) {
 		//        	this.value = value;
 		//        }
 		//		public Object getValue () {
 		//			return value;
 		//		}
 
 		public abstract Object getValue ();
 	}
 
 	public static class FieldWithValue extends HasAValue {
 		private String value = "Inner Field";
 
 		public void setValue (String value) {
 			this.value = value;
 		}
 
 		public String getValue () {
 			return value;
 		}
 	}
 
 	public void onHello (ActionEvent ae) {
 	}
 
 	public String getField () {
 		return field;
 	}
 
 	public void setCcValueMap (HashMap<String, HasAValue> ccValueMap) {
 		this.fieldWithValueMap = ccValueMap;
 	}
 
 	public HashMap<String, HasAValue> getCcValueMap () {
 		return fieldWithValueMap;
 	}
 }
 


JSP:


Code:
 <%@page contentType="text/html"%>
 <%@page pageEncoding="UTF-8"%>
 
 <%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
 <%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
 
 <%@taglib prefix="t" uri="/WEB-INF/eclnt"%>
 
 
 <!-- ========== CONTENT BEGIN ========== -->
 <f:view>
 <h:form>
 <f:subview id="Page3g_sv">
 <t:rowtitlebar id="g_1" />
 <t:rowheader id="g_2" />
 <t:rowbodypane id="g_3" >
 <t:row id="g_4" >
 <t:field id="g_5" text="#{d.Page3Bean.ccValueMap.S.value}" width="100" />
 <t:button id="g_6" text="Drück mich!" />
 </t:row>
 </t:rowbodypane>
 <t:rowstatusbar id="g_7" />
 <t:pageaddons id="g_pa"/>
 </f:subview>
 </h:form>
 </f:view>
 <!-- ========== CONTENT END ========== -->
 


 
Forum Index -> Development
Go to:   
Powered by JForum 2.1.6 © JForum Team