Looks like 3.0.0M3 was just released and the package structure is completely different. Unfortunately, the examples for 3.0.0M2 no longer work. I'm looking to instantiate my JSF beans by spring, and I don't know how to do it.
According to the example that ships with 3.0.0M2 (in the docs), you do this
<!-- a de.mindmatters.faces.spring.SpringBeanFactory used to define the scope of a Spring managed bean -->
<managed-bean>
<managed-bean-name>scopedAccessSpringBean</managed-bean-name>
<managed-bean-class>de.mindmatters.faces.spring.SpringBeanFactory</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
BUT, that class doesn't exist in 3.0.0M3 (and it doesn't even exist in 3.0.0M2!)
Without any kind of example, quickstart, or other such documentation. I'm not sure where to start. All I have are the Javadocs.
Can anyone tell me the right way to do what I'm trying to do with 3.0.0M3
Thanks
Dan
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The point is that the 3.0.0M2 docs say to instantiate de.mindmatters.faces.spring.SpringBeanFactory in place of your managed beans, and then presumably, that class will intelligently look in the spring configuration and instantiate the real bean.
How do I do that with the new, totally different class and package structure?
thanks
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
the documentation was completely out of date up to M2, we only just updated it with today's M3 release. SpringBeanFactory did vanish quite some time ag. It has been replaced by de.mindmatters.faces.spring.AbstractScope and its subclasses ApplicationScope, SessionScope and RequestScope. So since today, you shouldn't find SpringBeanFactory anywhere in the current documentation any more.
For an example of how to use the above mentioned new scope concept, have a look at webapp/WEB-INF/lib/faces-config-scope.xml within the testsuite. Just briefly: By choosing the appropriate factory bean, you define the scope your bean should appear in and then you've got three choices of how to specify the bean to be scoped:
- by id: your scope factory (managed-bean) has the same id as your bean (spring bean)
- by property targetBeanName: set the id of your bean
- by property targetBean: set a reference to your bean
Anyway, since we're approaching the next major release and the project has been going through some heavy refactoring and a lot of new features have been added, we introduced some backward incompatibilities. This might still occur with the next milestones, so don't expect the API to be rock solid until 3.0.0 is finally out. We're much more stable now than during the first releases, though. And we're trying to keep the user's refactoring inconveniences as low as possible while still maintaining a clean code base with the growing feature set.
Regards,
Thomas
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thank you. I'm not worried about backward compatibility, as this is the first time I've used jsf-spring. I was only worried that I couldn't make it work, and in fact it's still not. Please let me know what I'm doing wrong.
faces-config has a simple bean that I'd like to be a reference to a Spring bean
However, I get a PropertyNotFound exception. It is trying to evaluate my bean's property (anyUsersVisible) on RequestScope, and obviously that property doesn't exist
It also appears (from a breakpoint) that the constructor on my bean is not being called.
If there are docs that describe this sort of basic stuff, let me know. I hate to bother people with stuff like this. The old index.html of the docs had an example, but the new one doesn't.
Thanks for you help,
Dan
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Scope beans always should be in application scope. This might be confusing, but actually, they are FactoryBeans that have to be singletons (in application scope). The scope the target bean should be in is specified by the type of scope bean you use, not be the scope of the scope bean.
This might be the cause that the property is searched on the scope bean and not on the target bean - the scope bean just isn't recognized as factory and thus isn't asked for the target bean.
Apart from this, your code should be correct.
Concerning the missing example: In older versions, we explained all features on the index page, but since our feature set has grown quite a bit, this isn't feasible any more. We're shifting this to the still to be created cookbook.
HTH,
Thomas
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I made that change, and I'm seeing the same error. From looking at the code, I thought I wanted to have getObject called, because it calls createObject and creates my bean (or looks it up in my spring context)
So, changed my JSP to use #{myBeanName.object.property} instead of #{myBeanName.property)
Unfortunataly, I caused myself more problems... an NPE because this.name was not set in AbstractScope. So I need to set the name property, but to what? I thought it was sufficient to make the name of my faces bean (the RequestScope factory) the same as the name of my actual target bean in the spring context.
hmmm... any ideas?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Is jsf-spring configured properly? Maybe your managed-bean isn't handled by jsf-spring but by JSF itself? Please post your web.xml so I can analyze your problem further.
Regards,
Thomas
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
That's the wrong listener. You need to configure de.mindmatters.faces.spring.context.ContextLoaderListener. This one creates the spring context used by jsf-spring, the one you use is used to configure jsf components (validators, converters etc) via spring - one of the new features.
HTH,
Thomas
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Looks like 3.0.0M3 was just released and the package structure is completely different. Unfortunately, the examples for 3.0.0M2 no longer work. I'm looking to instantiate my JSF beans by spring, and I don't know how to do it.
According to the example that ships with 3.0.0M2 (in the docs), you do this
<!-- a de.mindmatters.faces.spring.SpringBeanFactory used to define the scope of a Spring managed bean -->
<managed-bean>
<managed-bean-name>scopedAccessSpringBean</managed-bean-name>
<managed-bean-class>de.mindmatters.faces.spring.SpringBeanFactory</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
BUT, that class doesn't exist in 3.0.0M3 (and it doesn't even exist in 3.0.0M2!)
Without any kind of example, quickstart, or other such documentation. I'm not sure where to start. All I have are the Javadocs.
Can anyone tell me the right way to do what I'm trying to do with 3.0.0M3
Thanks
Dan
SF ate my XML.
The point is that the 3.0.0M2 docs say to instantiate de.mindmatters.faces.spring.SpringBeanFactory in place of your managed beans, and then presumably, that class will intelligently look in the spring configuration and instantiate the real bean.
How do I do that with the new, totally different class and package structure?
thanks
Hi Dan,
the documentation was completely out of date up to M2, we only just updated it with today's M3 release. SpringBeanFactory did vanish quite some time ag. It has been replaced by de.mindmatters.faces.spring.AbstractScope and its subclasses ApplicationScope, SessionScope and RequestScope. So since today, you shouldn't find SpringBeanFactory anywhere in the current documentation any more.
For an example of how to use the above mentioned new scope concept, have a look at webapp/WEB-INF/lib/faces-config-scope.xml within the testsuite. Just briefly: By choosing the appropriate factory bean, you define the scope your bean should appear in and then you've got three choices of how to specify the bean to be scoped:
- by id: your scope factory (managed-bean) has the same id as your bean (spring bean)
- by property targetBeanName: set the id of your bean
- by property targetBean: set a reference to your bean
Anyway, since we're approaching the next major release and the project has been going through some heavy refactoring and a lot of new features have been added, we introduced some backward incompatibilities. This might still occur with the next milestones, so don't expect the API to be rock solid until 3.0.0 is finally out. We're much more stable now than during the first releases, though. And we're trying to keep the user's refactoring inconveniences as low as possible while still maintaining a clean code base with the growing feature set.
Regards,
Thomas
Thank you. I'm not worried about backward compatibility, as this is the first time I've used jsf-spring. I was only worried that I couldn't make it work, and in fact it's still not. Please let me know what I'm doing wrong.
faces-config has a simple bean that I'd like to be a reference to a Spring bean
<managed-bean>
<managed-bean-name>deactivateUserBean</managed-bean-name>
<managed-bean-class>de.mindmatters.faces.spring.RequestScope</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
My spring configuration has an identically-named bean:
<bean id="deactivateUserBean" class="com.carescience.soc.web.managedbeans.DeactivateUserListBean" singleton="false">
<property name="adminService" ref="adminService"/>
</bean>
However, I get a PropertyNotFound exception. It is trying to evaluate my bean's property (anyUsersVisible) on RequestScope, and obviously that property doesn't exist
2005-12-21 12:09:26,625 ERROR [[jsp]] Servlet.service() for servlet jsp threw exception
javax.faces.el.PropertyNotFoundException: Bean: de.mindmatters.faces.spring.RequestScope, property: anyUsersVisible
It also appears (from a breakpoint) that the constructor on my bean is not being called.
If there are docs that describe this sort of basic stuff, let me know. I hate to bother people with stuff like this. The old index.html of the docs had an example, but the new one doesn't.
Thanks for you help,
Dan
Scope beans always should be in application scope. This might be confusing, but actually, they are FactoryBeans that have to be singletons (in application scope). The scope the target bean should be in is specified by the type of scope bean you use, not be the scope of the scope bean.
This might be the cause that the property is searched on the scope bean and not on the target bean - the scope bean just isn't recognized as factory and thus isn't asked for the target bean.
Apart from this, your code should be correct.
Concerning the missing example: In older versions, we explained all features on the index page, but since our feature set has grown quite a bit, this isn't feasible any more. We're shifting this to the still to be created cookbook.
HTH,
Thomas
I made that change, and I'm seeing the same error. From looking at the code, I thought I wanted to have getObject called, because it calls createObject and creates my bean (or looks it up in my spring context)
So, changed my JSP to use #{myBeanName.object.property} instead of #{myBeanName.property)
Unfortunataly, I caused myself more problems... an NPE because this.name was not set in AbstractScope. So I need to set the name property, but to what? I thought it was sufficient to make the name of my faces bean (the RequestScope factory) the same as the name of my actual target bean in the spring context.
hmmm... any ideas?
Is jsf-spring configured properly? Maybe your managed-bean isn't handled by jsf-spring but by JSF itself? Please post your web.xml so I can analyze your problem further.
Regards,
Thomas
Here it is. All I added was your ConfigLoaderListener as the LAST listener in the file.
Hope the XML comes through ok
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>server</param-value>
</context-param>
<context-param>
<param-name>javax.faces.CONFIG_FILES</param-name>
<param-value>/WEB-INF/faces-config.xml</param-value>
</context-param>
<!-- Spring configuration -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:META-INF/applicationContext-*.xml</param-value>
</context-param>
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>soc</param-value>
</context-param>
<!-- Excel Export -->
<filter>
<filter-name>ResponseOverrideFilter</filter-name>
<filter-class>org.displaytag.filter.ResponseOverrideFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ResponseOverrideFilter</filter-name>
<url-pattern>*.jsf</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>ResponseOverrideFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
<!-- Acegi filter -->
<filter>
<filter-name>Acegi Filter Chain Proxy</filter-name>
<filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class>
<init-param>
<param-name>targetClass</param-name>
<param-value>
net.sf.acegisecurity.util.FilterChainProxy
</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Acegi Filter Chain Proxy</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- MyFaces listener -->
<listener>
<listener-class>
org.apache.myfaces.webapp.StartupServletContextListener
</listener-class>
</listener>
<!-- Spring listener -->
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<!-- Acegi listener -->
<listener>
<listener-class>
net.sf.acegisecurity.ui.session.HttpSessionEventPublisher
</listener-class>
</listener>
<!-- The listener used to load the jsf-spring-config context
(the pluggable JSF components). -->
<listener>
<listener-class>de.mindmatters.faces.spring.config.ConfigLoaderListener</listener-class>
</listener>
<!-- Faces Servlet -->
<servlet>
<servlet-name>FacesServlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Faces Servlet Mapping -->
<servlet-mapping>
<servlet-name>FacesServlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
<!-- session timeout for HIPAA -->
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<error-page>
<error-code>403</error-code>
<location>/login.jsp?error=2</location>
</error-page>
<!-- ### Security -->
<security-constraint>
<web-resource-collection>
<web-resource-name>Restricted</web-resource-name>
<description>Declarative security tests</description>
<url-pattern>/pages/*</url-pattern>
<url-pattern>/index.jsp</url-pattern>
<url-pattern>/login.jsp</url-pattern>
<url-pattern>/loginError.jsp</url-pattern>
<url-pattern>/logout.jsp</url-pattern>
<http-method>HEAD</http-method>
<http-method>GET</http-method>
<http-method>POST</http-method>
<http-method>PUT</http-method>
<http-method>DELETE</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>ROLE_SUITE_USER</role-name>
</auth-constraint>
<user-data-constraint>
<description>Secure login</description>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<realm-name>MainApp</realm-name>
<form-login-config>
<form-login-page>/login.jsp</form-login-page>
<form-error-page>/login.jsp?error=1</form-error-page>
</form-login-config>
</login-config>
<security-role>
<description>Care Management Suite User</description>
<role-name>ROLE_SUITE_USER</role-name>
</security-role>
</web-app>
That's the wrong listener. You need to configure de.mindmatters.faces.spring.context.ContextLoaderListener. This one creates the spring context used by jsf-spring, the one you use is used to configure jsf components (validators, converters etc) via spring - one of the new features.
HTH,
Thomas
You're saying replace Spring's ContextLoaderListener with your version?
No, you need spring's ContextLoaderListener to startup spring. And you need jsf-spring's ContextLoaderListener to startup jsf-spring.
Have a look at the testsuite for an example of how to setup your application.
This appears to solve it. Thanks!