Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Eager ApplicationScoped managed beans constructed multiple times

I have a bunch of eager ApplicationScoped managed beans. Some of them are injected into others by the ManagedProperty annotation, forming a tree of dependencies. Each depending bean manipulates its parent after construction.

However, it seems like a new instance is created for each injection, thus making previous manipulations undone. To my understanding, an ApplicationScoped bean should only be created once. Have I misunderstood or why is this happening? Is it because they are eager?

Here is an example:

ParentBean.java

package example;

import javax.annotation.PostConstruct;
import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;

@ManagedBean(eager = true)
@ApplicationScoped
public class ParentBean
{
    static int initCount = 0;

    // ...

    @PostConstruct
    public void init()
    {
        ++initCount; // Will end up being between 1 and 3. Expected always 1.

        // ...
    }
}

Child1Bean.java

package example;

import javax.annotation.PostConstruct;
import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;

@ManagedBean(eager = true)
@ApplicationScoped
public class Child1Bean
{
    @ManagedProperty("#{parentBean}") ParentBean parentBean;

    public ParentBean getParentBean()
    {
        return parentBean;
    }

    public void setParentBean(ParentBean parentBean)
    {
        this.parentBean = parentBean;
    }

    @PostConstruct
    public void init()
    {
        // manipulate parentBean
    }
}

Child2Bean.java

package example;

import javax.annotation.PostConstruct;
import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;

@ManagedBean(eager = true)
@ApplicationScoped
public class Child2Bean
{
    @ManagedProperty("#{parentBean}") ParentBean parentBean;

    public ParentBean getParentBean()
    {
        return parentBean;
    }

    public void setParentBean(ParentBean parentBean)
    {
        this.parentBean = parentBean;
    }

    @PostConstruct
    public void init()
    {
        // manipulate parentBean
    }
}
like image 605
Spomf Avatar asked Nov 12 '22 19:11

Spomf


1 Answers

I have hopefully resolved this problem on Tomcat 8 + Mojarra 2.2.0. In my case I just removed listener declaration from web.xml

<listener>
    <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
</listener>

Constructor seems to be called once afterwards.

About listener entry, there is a part of BalusC answer of this question.

In any case, the explicit registration of Mojarra's ConfigureListener in web.xml is actually only necessary to workaround old buggy servers such as GlassFish v3 and Jetty who failed to find the listener in Mojarra's TLD file. When deployed to a decent server, the whole entry is unnecessary.

like image 101
The Raven Avatar answered Nov 15 '22 11:11

The Raven