After activating HA on Payara (Hazelcast) I have noticed the following WARN messages in the log:
[2017-12-12T15:12:31.266+0800] [Payara 4.1] [WARNING] [] [javax.enterprise.web.core] [tid: _ThreadID=63 _ThreadName=http-thread-pool::http-listener-2(2)] [timeMillis: 1513062751266] [levelValue: 900] [[
StandardSession: Cannot serialize session attribute com.sun.faces.application.view.activeViewMaps for session 9914fe69fd67044327585dc07409]]
Digging into this I have ended up with button for manual serialization of the @ViewScope
beans contained in the sessionScope['com.sun.faces.application.view.activeViewMaps']
Map in order to locate the beans that cause this issue.
It turned out that the issue is caused by usage of the @EJB
in @ViewScoped
beans. There are several posts here that discuss this issue, but no one seems to provide a solution for clustered environment.
So basically there is a main question: how to properly use @EJB
(SLSB) in JSF @VeiwScoped
CDI beans in the clustered environment?
One of the possible solutions I saw – is something like this one: https://stackoverflow.com/a/10145618/2261312
The idea of the here-above mentioned solution – just to split ViewScoped
bean in two beans: @ViewScoped
with actual view-related logic, and EJB beans move to the separate @RequestScoped
bean, and inject the @RequestScoped
bean into @ViewScoped
bean in order to get access to @EJB
services.
But this look absolutely weird from the code-syntax / design point of view… Any other suggestions here?
Thanks!
Used software: JSF 2.3.3 (Mojarra), Payara Server 4.1.2.174 (Full), Hazelcast based cluster
And the links I have found so far:
- @EJB in @ViewScoped @ManagedBean causes java.io.NotSerializableException
- ViewScoped Bean, EJB and SlectMenu Issue
- Injected EJB Reference Lost in ViewScoped JSF Bean
- @EJB in @ViewScoped managed bean causes java.io.NotSerializableException
Update 1:
I did several additional tests and have found out, that even though WARN message StandardSession: Cannot serialize session attribute com.sun.faces.application.view.activeViewMaps for session ...
appears in the log, cluster works fine, and end-user can switch between cluster nodes without having any issues with proper functionality of the ViewScoped CDI Beans in the JSF app: SLSB injected with @EJB
still work even after fail-over to other cluster nodes.
Thus basically the question now is the following: should this WARN message be ignored, or it anyway has to be addressed?
Few words about test case scenario:
1) The deployment includes three servers:
- Server 1: Payara DAS + Payara Cluster Node 1
- Server 2: Payara Cluster Node 2
- Server 3: Nginx which acts as revers-proxy + load-balancer and distributes traffic between nodes
2) JSF Application:
2.1) JSF View:
<ui:composition>
<ui:define name="content">
<h:form id="ft1">
mark2 = #{testBean.mark2}<br/>
mark3 = #{testBean.mark3}<br/>
<p:commandButton value="TEST SER" action="#{testBean.test1()}" /><br/>
<p:commandButton value="TEST2" action="#{testBean.test2()}" update="@form"/>
</h:form>
</ui:define>
</ui:composition>
2.2) JSF ViewScope Bean:
package ua.local.beans;
import ....
import javax.faces.view.ViewScoped;
import ....
@Named
@ViewScoped
public class TestBean implements Serializable {
private static final long serialVersionUID = -4596312102341014148L;
@EJB
private LogDao _logDao;
private long mark2 = 0;
private long mark3 = 0;
public void test1() {
try {
File serFile = File.createTempFile("debug_", ".ser");
FileOutputStream fileOut = new FileOutputStream(serFile);
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(this);
out.close();
fileOut.close();
System.out.printf("TEST: Serialized data is saved in " + serFile.getAbsolutePath());
} catch (Exception i) {
i.printStackTrace();
}
}
public void test2() {
System.out.println(">> found LOGS: " + _logDao.findAll().size());
mark2 = mark3;
mark3 = System.currentTimeMillis();
}
public long getMark2() {
return mark2;
}
public long getMark3() {
return mark3;
}
}
2.3) SLSB:
@Stateless
public class LogDaoMongoImpl extends AbstractMongoDAO<Log> implements LogDao, Serializable {
...
}
This works absolutely fine in clustered environment even despite WARN message.