ad-inf
ad-inf

Reputation: 1570

JSF 2 - replacing faces-config configuration for Managed Bean by Annotation

I am using MyFaces JSF 2.0 in which I replaced faces-config

<managed-bean>
    <managed-bean-name>myBean</managed-bean-name>
    <managed-bean-class>com.myBean</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
</managed-bean>
    with
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

@ManagedBean
@SessionScoped
public class MyBean  implements Serializable {

The error I encounter is as below. It works if I restore the faces-config change. What I am doing wrong?

0000008e FaceletViewDe E   Error Rendering View[/test.xhtml]
                             javax.faces.FacesException: Property facesContext     references object in a scope with shorter lifetime than the target scope session
at     org.apache.myfaces.config.ManagedBeanBuilder.initializeProperties(ManagedBeanBuilder.java:324)
at     org.apache.myfaces.config.ManagedBeanBuilder.buildManagedBean(ManagedBeanBuilder.java:169)
at org.apache.myfaces.el.unified.resolver.ManagedBeanResolver.createManagedBean(ManagedBeanResolver.java:303)
at org.apache.myfaces.el.unified.resolver.ManagedBeanResolver.getValue(ManagedBeanResolver.java:266)

Upvotes: 0

Views: 1782

Answers (2)

BalusC
BalusC

Reputation: 1109695

This error indicates that you've a

@ManagedBean
@SessionScoped
public class MyBean implements Serializable {

    @ManagedProperty("#{facesContext}")
    private FacesContext facesContext;

}

This is not possible and this is actually also bad design. The FacesContext is specific to the current request and changes on every HTTP request. But a session scoped bean is created only once during the HTTP session and the injected FacesContext instance would only refer to the one of the HTTP request which was involved during the creation of the session scoped bean. In any subsequent requests within the same session this would only result in a major problem because the FacesContext instance of the previous request would not be valid anymore.

You need to remove the FacesContext property (and also any other properties which you obtained from ExternalContext). You should instead be retrieving them in the very same method block as where you need it.

@ManagedBean
@SessionScoped
public class MyBean implements Serializable {

    public void someMethod() {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        // ...
    }

}

Upvotes: 1

lu4242
lu4242

Reputation: 2318

You can't inject facesContext using @ManagedProperty in session scope, because the session bean "lives" longer than facesContext. You have to create a request scope bean and inject facesContext and your session bean and do the job there, or call FacesContext.getCurrentInstance() inside the session bean.

Upvotes: 0

Related Questions