After upgrading from JSF-Spring 3.0 to JSF-Spring 4.0.1 one of my JSF-Pages doesn't work anymore.
This is my configuration in web.xml
<!-- Spring -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Sprint Request -->
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<!-- Spring-JSF -->
<listener>
<listener-class>de.mindmatters.faces.spring.context.ContextLoaderListener</listener-class>
</listener>
In my JSF-Page I have the follwoing entry:
<t:dataTable binding="#{theBean.htable}" ......>
It means that the dataTable is binded to a variable in the backing Bean.
With JSF-Spring 4.0.1 the value in the backing bean is always null.
Has anybody an idea what is going wrong, or is feature with this version not usable?
Regards
Wolfgang
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
1. I defined my Managed-Beans not in faces-config.xml but in the Spring Enviroment.
Example:
<bean id="testBean" class="de.lido.vu.bean.TestBean" scope="request">
</bean>
With JSF-Spring 3.0 an attribute singleton="true" had to be added.
2. If using this and not have org.springframework.web.context.request.RequestContextListener
I get the following error:
Caused by: java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request? If you are actually operating within a web request and still receive this message,your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
In the beginning I also used VariableResolver but for some reasons I changed it and used JSF-Spring which have more power.
In the quickstart example they say that the listener de.mindmatters.faces.spring.context.ContextLoaderListener had to be defined
after the Spring-Listener.
Maybe someone has an example how to define Manged-Beans not in faces-config.xml. With Spring-JSF 3.0 everything works fine.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
binding components on a managed bean is tested and should work. I've tested this feature with testcases and a few of productive web apps which use dataTable-binding for row selection. Nevertheless, could you please send me the whole configuration and implementation which does not work. Then i try to figure out what the problem is.
Regards
Andreas Kuhrwahl
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I think the problem is in the complete enviroment which I'm using: MyFaces-AJAX4JSF-Spring etc.
In my opionion the problem comes from AJAX4JSF which I'm using here.
My method setHtable(..) is definitly not called. Currently I don't know why.
In the view the table is available, because I can get the table with this code:
(HtmlDataTable)FacesContext.getCurrentInstance().getViewRoot().findComponent("form1:spezTable");
On some events in the table I make an AJAX-Call and which this calls the binding doesn't work.
It was working before JSF-Spring 4.0.1. Normally AJAX4JSF requests are identically handled as normal requests but there must be something different.
In which class of JSF-Spring is the binding done. This information would save me some time and I can start research
with my enviroment.
Regards
Wolfgang
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
thank's for the hint. After doing some research and adding Debug I can say that the method doPerComponentActions is
in my enviroment never called.
The problem is in the method RestoreViewPhase#executePhase
I'll try to explain the problem
Here the method:
1 protected final void executePhase(final FacesContext context) {
2 if (context == null) {
3 throw new FacesException("FacesContext");
4 }
5 UIViewRoot viewRoot = context.getViewRoot();
6 if (viewRoot != null) {
7 System.out.println("viewRoot!=null");
8 Locale locale = context.getExternalContext().getRequestLocale();
9 context.getViewRoot().setLocale(locale);
10 executePerComponentActions(context, viewRoot);
11 } else {
12 ViewId viewId = deriveViewId(context);
13 if (viewId.get() == null) {
14 throw new FacesException("ViewId not derived");
15 }
16 ViewHandler viewHandler = context.getApplication().getViewHandler();
17 boolean isViewBuilder = viewHandler instanceof ViewBuilder;
18 viewRoot = restoreView(context, viewHandler, viewId.get());
19 if (viewRoot == null && viewId.isRequestParameter()
20 && isViewBuilder) {
21 viewRoot = buildView(context, (ViewBuilder) viewHandler, viewId
22 .get());
23 }
24 if (viewRoot == null) {
25 viewRoot = createView(context, viewHandler, viewId.get());
26 }
27 context.setViewRoot(viewRoot);
28 if (isViewBuilder) {
29 executePerComponentActions(context, viewRoot);
30 }
31
32 }
33 }
The condition in line 6 is false, because viewRoot is null. I don't know why at this time the viewRoot is null it shouldn't.
In line 17 isViewBuilder is set to false because I don't use Facelets and therefor line 29 is never reached.
The question know is. Why get's context.getViewRoot() null. As explaind in my posting before when using the context in my
Managed-Bean the viewRoot isn't null.
For every Request which come's in the viewRoot is null. The object context passed in to the function is of type
org.apache.myfaces.context.servlet.ServletFacesContextImpl
Maybe the RestoreViewExecutor of MyFaces has to be called before executing this, because there the viewRoot is set, but how can I achive this.
Regards
Wolfgang
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
After upgrading from JSF-Spring 3.0 to JSF-Spring 4.0.1 one of my JSF-Pages doesn't work anymore.
This is my configuration in web.xml
<!-- Spring -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Sprint Request -->
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<!-- Spring-JSF -->
<listener>
<listener-class>de.mindmatters.faces.spring.context.ContextLoaderListener</listener-class>
</listener>
In my JSF-Page I have the follwoing entry:
<t:dataTable binding="#{theBean.htable}" ......>
It means that the dataTable is binded to a variable in the backing Bean.
With JSF-Spring 4.0.1 the value in the backing bean is always null.
Has anybody an idea what is going wrong, or is feature with this version not usable?
Regards
Wolfgang
You don't need jsf-spring library. Just use spring and jsf libraries. Do this config and it should work -
In web.xml
<listener>
<listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
and in faces config
<variable-resolver>org.springframework.web.jsf.DelegatingVariableResolver</variable-resolver>
This doesn't work, because
1. I defined my Managed-Beans not in faces-config.xml but in the Spring Enviroment.
Example:
<bean id="testBean" class="de.lido.vu.bean.TestBean" scope="request">
</bean>
With JSF-Spring 3.0 an attribute singleton="true" had to be added.
2. If using this and not have org.springframework.web.context.request.RequestContextListener
I get the following error:
Caused by: java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request? If you are actually operating within a web request and still receive this message,your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
In the beginning I also used VariableResolver but for some reasons I changed it and used JSF-Spring which have more power.
In the quickstart example they say that the listener de.mindmatters.faces.spring.context.ContextLoaderListener had to be defined
after the Spring-Listener.
Maybe someone has an example how to define Manged-Beans not in faces-config.xml. With Spring-JSF 3.0 everything works fine.
Hi Wolfgang,
binding components on a managed bean is tested and should work. I've tested this feature with testcases and a few of productive web apps which use dataTable-binding for row selection. Nevertheless, could you please send me the whole configuration and implementation which does not work. Then i try to figure out what the problem is.
Regards
Andreas Kuhrwahl
Hi Andreas,
I think the problem is in the complete enviroment which I'm using: MyFaces-AJAX4JSF-Spring etc.
In my opionion the problem comes from AJAX4JSF which I'm using here.
My method setHtable(..) is definitly not called. Currently I don't know why.
In the view the table is available, because I can get the table with this code:
(HtmlDataTable)FacesContext.getCurrentInstance().getViewRoot().findComponent("form1:spezTable");
On some events in the table I make an AJAX-Call and which this calls the binding doesn't work.
It was working before JSF-Spring 4.0.1. Normally AJAX4JSF requests are identically handled as normal requests but there must be something different.
In which class of JSF-Spring is the binding done. This information would save me some time and I can start research
with my enviroment.
Regards
Wolfgang
Hi Wolfgang,
it's done in de.mindmatters.faces.lifecycle.RestoreViewPhase#doPerComponentActions(FacesContext, UIComponent).
Regards
Andy
Hi Andreas,
thank's for the hint. After doing some research and adding Debug I can say that the method doPerComponentActions is
in my enviroment never called.
The problem is in the method RestoreViewPhase#executePhase
I'll try to explain the problem
Here the method:
1 protected final void executePhase(final FacesContext context) {
2 if (context == null) {
3 throw new FacesException("FacesContext");
4 }
5 UIViewRoot viewRoot = context.getViewRoot();
6 if (viewRoot != null) {
7 System.out.println("viewRoot!=null");
8 Locale locale = context.getExternalContext().getRequestLocale();
9 context.getViewRoot().setLocale(locale);
10 executePerComponentActions(context, viewRoot);
11 } else {
12 ViewId viewId = deriveViewId(context);
13 if (viewId.get() == null) {
14 throw new FacesException("ViewId not derived");
15 }
16 ViewHandler viewHandler = context.getApplication().getViewHandler();
17 boolean isViewBuilder = viewHandler instanceof ViewBuilder;
18 viewRoot = restoreView(context, viewHandler, viewId.get());
19 if (viewRoot == null && viewId.isRequestParameter()
20 && isViewBuilder) {
21 viewRoot = buildView(context, (ViewBuilder) viewHandler, viewId
22 .get());
23 }
24 if (viewRoot == null) {
25 viewRoot = createView(context, viewHandler, viewId.get());
26 }
27 context.setViewRoot(viewRoot);
28 if (isViewBuilder) {
29 executePerComponentActions(context, viewRoot);
30 }
31
32 }
33 }
The condition in line 6 is false, because viewRoot is null. I don't know why at this time the viewRoot is null it shouldn't.
In line 17 isViewBuilder is set to false because I don't use Facelets and therefor line 29 is never reached.
The question know is. Why get's context.getViewRoot() null. As explaind in my posting before when using the context in my
Managed-Bean the viewRoot isn't null.
For every Request which come's in the viewRoot is null. The object context passed in to the function is of type
org.apache.myfaces.context.servlet.ServletFacesContextImpl
Maybe the RestoreViewExecutor of MyFaces has to be called before executing this, because there the viewRoot is set, but how can I achive this.
Regards
Wolfgang
Hi Wolfgang,
that's a bug. Thank you very much! Line 29 has to be 'if(!isViewBuilder)...' - i will build a new distribution today evening
Hi Andreas,
the problem is solved. Now the binding works as expected.
Could you please look at the Bug I reported here:
http://sourceforge.net/tracker/index.php?func=detail&aid=1712219&group_id=107519&atid=647833
I think the change will help everybody who uses AJAX4JSF and JSF-Spring.
Thank you
Wolfgang