0

My CDI-managed @Named bean's postConstruct method is being invoked multiple times per view on page refresh in browser. However, @PreDestroy is never called.

@Postconstruct method called multiple times in a CDI-managed @Viewscoped bean is an old problem with many suggestions how to solve this issue. Many of them can be found here on Stack Overflow. I've tried all of them, but none of them helped.

I have even created a simple project with just one single bean to help everyone reproduce the problem. It can be found on GitHub.

I've tried

  • Checked JSF implementation version Mojarra 2.2.12
  • Checked WELD version (2.3.2)
  • Checked annotations (both annotations are from CDI package)
  • Deploy to different Application servers (Wildfly 9, WildFly 10, Payara 4.1.1.161_1) - nothing worked.
  • Checked the XHTML page for and bindings. Did not work.
  • javax.faces.PARTIAL_STATE_SAVING - again, did not work.
  • There is no ViewExpired exception
  • There are no other jars in the classpath (included in the WAR). There is just a provided JEE-7 dependency. The WAR itself only has 2,6 kB.
  • Prettyfaces or any other framework are used (see previous bullet).

The CDI-Managed bean looks like this:

package com.viewscopetest;

import javax.annotation.PostConstruct;
import javax.inject.Named;
import javax.faces.view.ViewScoped;
import java.io.Serializable;

@Named
@ViewScoped
public class TestViewBean implements Serializable {


    private String hello;

    public String getHello() {
        return hello;
    }

    public void setHello(String hello) {
        this.hello = hello;
    }

    @PostConstruct
    private void postConstruct() {
        hello = "Hello";
        System.out.println("Again");
    }
}

The view looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:form id="test">
        <h:outputLabel value="#{testViewBean.hello}"/>
</h:form>
</html>

There is an near-empty faces-config.xml

<?xml version='1.0' encoding='UTF-8'?>
<faces-config version="2.2" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
    http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd">

</faces-config>

And a very basic web.xml

<web-app
        version="3.1"
        xmlns="http://xmlns.jcp.org/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">

    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>index.xhtml</welcome-file>
    </welcome-file-list>
</web-app>

Finally, a very basic beans.xml configuration

<?xml version="1.0" encoding="UTF-8"?>
<beans
        xmlns="http://xmlns.jcp.org/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
                      http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
        bean-discovery-mode="all">
</beans>

All those configuration files are stored in WEB-INF folder (beans.xml, faces-config.xml, web.xml).

Nothing else is really present in the folder. Here are some informations about the environment (taken from WildFly 9 log).

[2016-05-07 12:29:46,379] Artifact Gradle : com.test : viewscopetest-0.1.war: Artifact is being deployed, please wait...
12:29:46,532 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-7) WFLYSRV0027: Starting deployment of "viewscopetest-0.1.war" (runtime-name: "viewscopetest-0.1.war")
12:29:46,825 INFO  [org.jboss.weld.deployer] (MSC service thread 1-5) WFLYWELD0003: Processing weld deployment viewscopetest-0.1.war
12:29:46,871 INFO  [org.hibernate.validator.internal.util.Version] (MSC service thread 1-5) HV000001: Hibernate Validator 5.2.3.Final
12:29:47,003 INFO  [org.jboss.weld.deployer] (MSC service thread 1-6) WFLYWELD0006: Starting Services for CDI deployment: viewscopetest-0.1.war
12:29:47,029 INFO  [org.jboss.weld.Version] (MSC service thread 1-6) WELD-000900: 2.3.2 (Final)
12:29:47,078 INFO  [org.jboss.weld.deployer] (MSC service thread 1-3) WFLYWELD0009: Starting weld service for deployment viewscopetest-0.1.war
12:29:47,766 INFO  [javax.enterprise.resource.webcontainer.jsf.config] (ServerService Thread Pool -- 58) Initializing Mojarra 2.2.12-jbossorg-2 20150729-1131 for context '/viewscopetest-0.1'
12:29:48,085 INFO  [org.wildfly.extension.undertow] (ServerService Thread Pool -- 58) WFLYUT0021: Registered web context: /viewscopetest-0.1
12:29:48,099 INFO  [org.jboss.as.server] (management-handler-thread - 2) WFLYSRV0010: Deployed "viewscopetest-0.1.war" (runtime-name : "viewscopetest-0.1.war")
[2016-05-07 12:29:48,113] Artifact Gradle : com.test : viewscopetest-0.1.war: Artifact is deployed successfully
[2016-05-07 12:29:48,113] Artifact Gradle : com.test : viewscopetest-0.1.war: Deploy took 1 735 milliseconds

The problem is, the @VieScoped bean behaves like a request-scoped one. On page refresh, I'd expect the bean to be reused, instead of re-creating it and calling @PostConstruct method again.

Community
  • 1
  • 1
Pavel Pscheidl
  • 334
  • 3
  • 11
  • You're not terribly clear on the concrete problem. I'm not seeing a form anywhere in your github project. Only a GET page with some Hello World output. What exactly is the use case and what exactly is the expected behavior and what exactly is the unexpected behavior? As it stands now, it sounds much like that expectations are simply wrong. Also, if you have read "many questions" on them, you must als have seen http://stackoverflow.com/q/5541813, but you've nowhere in your question excluded e.g. the HTTP session from being the cause. – BalusC May 07 '16 at 11:27
  • As I guessed, you misunderstood `@ViewScoped`. – BalusC May 07 '16 at 12:00

0 Answers0