SFSB prolem during state replication in HA cluster (3) ? (so
marcoantonioni Apr 5, 2004 5:51 AM<<< the source code and configuration only for stateful EJB >>>
========================= TestHAEjbStatefulBean.java ================================================
package it.ibm.com.it42021.test.ejb;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.rmi.RemoteException;
import java.util.Random;
import javax.ejb.EJBException;
import javax.ejb.EJBHome;
import javax.ejb.EJBObject;
import javax.ejb.Handle;
import javax.ejb.RemoveException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
/**
* @author ....
*/
public class TestHAEjbStatefulBean implements SessionBean, TestHAEjbStatefulRemote {
public SessionContext ctx = null;
public String beanName = null;
public int maxItems = 0;
public int nextItem = 0;
public TestHAEjbStatefulBean() {
super();
System.out.println("CTOR: TestHAEjbStatefulBean");
}
public void ejbActivate() throws EJBException, RemoteException {
System.out.println("ejbActivate");
}
public void ejbPassivate() throws EJBException, RemoteException {
System.out.println("ejbPassivate");
}
public void ejbRemove() throws EJBException, RemoteException {
System.out.println("ejbRemove: "+beanName);
}
public void setSessionContext(SessionContext ctx) throws EJBException, RemoteException {
this.ctx = ctx;
System.out.println("setSessionContext");
}
public EJBHome getEJBHome() throws RemoteException {
EJBHome home = null;
if ( ctx != null ) {
home = ctx.getEJBHome();
}
System.out.println("getEJBHome: "+home);
return home;
}
public Handle getHandle() throws RemoteException {
Handle handle = null;
if ( ctx != null ) {
EJBObject object = ctx.getEJBObject();
if ( object != null ) {
handle = object.getHandle();
}
}
System.out.println("getHandle: "+handle);
return handle;
}
public Object getPrimaryKey() throws RemoteException {
Object key = null;
if ( ctx != null ) {
EJBObject object = ctx.getEJBObject();
if ( object != null ) {
key = object.getPrimaryKey();
}
}
System.out.println("getPrimaryKey: "+key);
return key;
}
public boolean isIdentical(EJBObject obj) throws RemoteException {
System.out.println("isIdentical: "+obj);
return false;
}
public void remove() throws RemoteException, RemoveException {
System.out.println("remove: "+beanName);
}
public void ejbCreate(String beanName) {
this.beanName = beanName;
maxItems = new Random().nextInt( 3 ) + 1;
nextItem = maxItems;
System.out.println("ejbCreate: bean ["+ beanName + "] with [" +maxItems+"] items to consume.");
}
public String whoAreYou(String requester) throws RemoteException {
String serverName = null;
String answer = null;
try {
serverName = InetAddress.getLocalHost().getHostName();
} catch (UnknownHostException e) {
try {
serverName = InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e1) {
serverName = "<unknown host>";
}
}
answer = "[from requester="+requester+"] bean ["+beanName+"] from server ["+serverName+"]";
System.out.println("whoAreYou: "+beanName+", requester: "+requester);
return answer;
}
public int getMaxItems() throws RemoteException {
System.out.println("getMaxItems: "+beanName+", maxItems: "+maxItems);
return maxItems;
}
public int getNextItem() throws RemoteException {
if ( nextItem < 0 ) {
throw new RemoteException("No more items.");
}
System.out.println("getNextItem: "+beanName+", nextItem: "+nextItem);
return nextItem--;
}
// JBoss 3.2.x
public boolean isModified() {
System.out.println("isModified: false");
return false;
}
}
======================== TestHAEjbStatefulHomeRemote =====================================================
package it.ibm.com.it42021.test.ejb;
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EJBHome;
/**
* @author ...
*/
public interface TestHAEjbStatefulHomeRemote extends EJBHome {
public TestHAEjbStatefulRemote create(String beanName) throws RemoteException, CreateException;
}
======================== TestHAEjbStatefulRemote =====================================================
package it.ibm.com.it42021.test.ejb;
import java.rmi.RemoteException;
import javax.ejb.EJBObject;
/**
* @author ...
*/
public interface TestHAEjbStatefulRemote extends EJBObject {
public String whoAreYou(String requester) throws RemoteException;
public int getMaxItems() throws RemoteException;
public int getNextItem() throws RemoteException;
}
========================== ejb-jar.xml =====================================================
<?xml version="1.0"?>
<!DOCTYPE ejb-jar PUBLIC
"-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN"
"http://java.sun.com/dtd/ejb-jar_2_0.dtd">
<ejb-jar>
<enterprise-beans>
<ejb-name>TestHAEjbStateless</ejb-name>
it.ibm.com.it42021.test.ejb.TestHAEjbStatelessHomeRemote
it.ibm.com.it42021.test.ejb.TestHAEjbStatelessRemote
<ejb-class>it.ibm.com.it42021.test.ejb.TestHAEjbStatelessBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
<security-identity><use-caller-identity/></security-identity>
<ejb-name>TestHAEjbStateful</ejb-name>
it.ibm.com.it42021.test.ejb.TestHAEjbStatefulHomeRemote
it.ibm.com.it42021.test.ejb.TestHAEjbStatefulRemote
<ejb-class>it.ibm.com.it42021.test.ejb.TestHAEjbStatefulBean</ejb-class>
<session-type>Stateful</session-type>
<transaction-type>Container</transaction-type>
<security-identity><use-caller-identity/></security-identity>
</enterprise-beans>
</ejb-jar>
========================== jboss.xml =====================================================
<?xml version="1.0"?>
<!-- Esempio di descrittore per EJB in HA -->
<enterprise-beans>
<ejb-name>TestHAEjbStateless</ejb-name>
<jndi-name>ejb/TestHAEjbStateless</jndi-name>
true
<ejb-name>TestHAEjbStateful</ejb-name>
<jndi-name>ejb/TestHAEjbStateful</jndi-name>
true
<!-- i've tried with and without spefic infos about cluster-config -->
<cluster-config>
<partition-name>DefaultPartition</partition-name>
<home-load-balance-policy>org.jboss.ha.framework.interfaces.RoundRobin</home-load-balance-policy>
<!-- i've tried all possible combinations -->
<bean-load-balance-policy>org.jboss.ha.framework.interfaces.RoundRobin</bean-load-balance-policy>
<!-- bean-load-balance-policy>org.jboss.ha.framework.interfaces.FirstAvailable</bean-load-balance-policy -->
<!-- bean-load-balance-policy>org.jboss.ha.framework.interfaces.FirstAvailableIdenticalAllProxies</bean-load-balance-policy -->
<session-state-manager-jndi-name>/HASessionState/Default</session-state-manager-jndi-name>
</cluster-config>
</enterprise-beans>
============================= ServletTestHAJBossEjbStateful ==========================================
package it.ibm.com.it42021.test.web;
import it.ibm.com.it42021.test.ejb.TestHAEjbStatefulHomeRemote;
import it.ibm.com.it42021.test.ejb.TestHAEjbStatefulRemote;
import it.ibm.com.it42021.test.ejb.TestHAEjbStatelessHomeRemote;
import java.io.IOException;
import java.rmi.RemoteException;
import java.util.Properties;
import javax.ejb.CreateException;
import javax.ejb.RemoveException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author ...
*/
public class ServletTestHAJBossEjbStateful extends HttpServlet {
private static final String _paramNameProviderUrl = "providerUrl";
private static final String _paramNameResultJsp = "resultJsp";
private static final String _defaultJBossHAJNDIServer = "localhost:1100";
private static final String _defaultJBossNCtxFactory = "org.jnp.interfaces.NamingContextFactory";
private static final String _ejbJndiName = "ejb/TestHAEjbStateful";
private static final String _requesterName = "requesterName";
private static final String _beanName = "beanName";
private static final String _loops = "loops";
private static final String _answerBean = "answerBean";
private static String _resultJsp = "result.jsp";
private InitialContext ctx = null;
private TestHAEjbStatefulHomeRemote home = null;
private TestHAEjbStatefulRemote bean = null;
public ServletTestHAJBossEjbStateful() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
execute(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
execute(request, response);
}
public void destroy() {
super.destroy();
if (ctx != null) {
try {
ctx.close();
} catch (NamingException e) {
}
}
}
public void init(ServletConfig config) throws ServletException {
super.init(config);
String providerUrl = null;
String param = null;
param = config.getInitParameter(_paramNameProviderUrl);
if (param != null) {
providerUrl = param;
} else {
// default HA-JNDI for JBoss
providerUrl = _defaultJBossHAJNDIServer;
}
param = config.getInitParameter(_paramNameResultJsp);
if (param != null) {
_resultJsp = param;
}
Properties jndiProps = new Properties();
jndiProps.put(Context.PROVIDER_URL, providerUrl);
jndiProps.put(Context.INITIAL_CONTEXT_FACTORY, _defaultJBossNCtxFactory);
System.out.println("Using: " + Context.PROVIDER_URL+" = "+providerUrl);
System.out.println("Using: " + Context.INITIAL_CONTEXT_FACTORY+" = "+_defaultJBossNCtxFactory);
System.out.println("Using: result jsp = "+_resultJsp);
try {
ctx = new InitialContext(jndiProps);
// get home here to use balancing
home = (TestHAEjbStatefulHomeRemote) ctx.lookup(_ejbJndiName);
} catch (NamingException e) {
throw new ServletException(e);
}
}
protected void execute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String result = null;
String name = request.getParameter(_requesterName);
String beanName = request.getParameter(_beanName);
String strLoops = request.getParameter(_loops);
System.out.println("name: "+name+" beanName: "+beanName+" strLoops: "+strLoops);
int loops = 1;
try {
loops = Integer.parseInt(strLoops);
} catch (NumberFormatException e) {
}
if (name == null) {
name = "anonimo";
}
if (beanName == null) {
beanName = "bean anonimo";
}
StringBuffer sb = new StringBuffer();
sb.append("<table border=\"1\">");
bean = null;
try {
for (int i = 0; i < loops; i++) {
bean = home.create(beanName);
result = testEjb(name);
sb.append(""+(i+1)+"");
sb.append(result);
sb.append("");
try {
bean.remove();
} catch (RemoveException e2) {
e2.printStackTrace();
}
bean = null;
}
} catch (RemoteException e1) {
sb.append(""+e1.getMessage()+"");
} catch (CreateException e1) {
sb.append(""+e1.getMessage()+"");
} finally {
if ( bean != null ) {
try {
bean.remove();
} catch (RemoteException e2) {
e2.printStackTrace();
} catch (RemoveException e2) {
e2.printStackTrace();
}
}
}
sb.append("");
request.setAttribute(_answerBean, sb.toString());
request.getRequestDispatcher(_resultJsp).forward(request, response);
}
private String testEjb(String name) {
String result = null;
try {
result = bean.whoAreYou(name);
int max = bean.getMaxItems();
result += " max items ["+max+"]";
for (int i = 0; i < max; i++) {
result += " <"+bean.getNextItem()+">";
}
} catch (RemoteException e) {
result = e.getMessage();
}
return result;
}
}
================= cluster-service.xml (from BE1 configs, BE2 is identical) =======================================
<?xml version="1.0" encoding="UTF-8"?>
<!-- ===================================================================== -->
<!-- -->
<!-- Sample Clustering Service Configuration -->
<!-- -->
<!-- ===================================================================== -->
<!-- ==================================================================== -->
<!-- Cluster Partition: defines cluster -->
<!-- ==================================================================== -->
<!-- Name of the partition being built -->
DefaultPartition
<!-- Determine if deadlock detection is enabled -->
False
<!-- The JGroups protocol configuration -->
<!-- UDP: if you have a multihomed machine,
set the bind_addr attribute to the appropriate NIC IP address -->
bind_addr="192.168.1.9"
<!-- UDP: On Windows machines, because of the media sense feature
being broken with multicast (even after disabling media sense)
set the loopback attribute to true -->
<UDP mcast_addr="228.1.2.3" mcast_port="45566"
ip_ttl="64" ip_mcast="true"
mcast_send_buf_size="150000" mcast_recv_buf_size="80000"
ucast_send_buf_size="150000" ucast_recv_buf_size="80000"
loopback="true" />
<PING timeout="2000" num_initial_members="3"
up_thread="true" down_thread="true" />
<MERGE2 min_interval="5000" max_interval="10000" />
<FD shun="true" up_thread="true" down_thread="true"
timeout="2500" max_tries="5" />
<VERIFY_SUSPECT timeout="3000" num_msgs="3"
up_thread="true" down_thread="true" />
<pbcast.NAKACK gc_lag="50" retransmit_timeout="300,600,1200,2400,4800"
up_thread="true" down_thread="true" />
<pbcast.STABLE desired_avg_gossip="20000"
up_thread="true" down_thread="true" />
<UNICAST timeout="5000" window_size="100" min_threshold="10"
down_thread="true" />
<FRAG frag_size="8192"
down_thread="true" up_thread="true" />
<pbcast.GMS join_timeout="5000" join_retry_timeout="2000"
shun="true" print_local_addr="true" />
<pbcast.STATE_TRANSFER up_thread="true" down_thread="true" />
<!-- ==================================================================== -->
<!-- HA Session State Service for SFSB -->
<!-- ==================================================================== -->
jboss:service=DefaultPartition
<!-- Name of the partition to which the service is linked -->
DefaultPartition
<!-- JNDI name under which the service is bound -->
/HASessionState/Default
<!-- Max delay before cleaning unreclaimed state.
Defaults to 30*60*1000 => 30 minutes -->
0
<!-- ==================================================================== -->
<!-- HA JNDI -->
<!-- ==================================================================== -->
jboss:service=DefaultPartition
<!-- Name of the partition to which the service is linked -->
DefaultPartition
<!-- bind address of HA JNDI RMI endpoint -->
${jboss.bind.address}
<!-- RmiPort to be used by the HA-JNDI service
once bound. 0 => auto. -->
0
<!-- Port on which the HA-JNDI stub is made available -->
11100
<!-- Backlog to be used for client-server RMI
invocations during JNDI queries -->
50
<!-- Multicast Address and Group used for auto-discovery -->
230.0.0.4
1102
<!-- IP Address to which should be bound: the Port, the RmiPort and
the AutoDiscovery multicast socket. -->
<!-- Client socket factory to be used for client-server
RMI invocations during JNDI queries -->
<!--attribute name="ClientSocketFactory">custom</attribute-->
<!-- Server socket factory to be used for client-server
RMI invocations during JNDI queries -->
<!--attribute name="ServerSocketFactory">custom</attribute-->
${jboss.bind.address}
<!--
0
custom
custom
-->
<!-- ==================================================================== -->
<!-- Distributed cache invalidation -->
<!-- ==================================================================== -->
jboss:service=DefaultPartition
jboss.cache:service=InvalidationManager
jboss.cache:service=InvalidationManager
DefaultPartition
DefaultJGBridge
=======================================================================
... other useful infos ...
===============================================================================================
== JBoss version
===============================================================================================
...
09:58:41,250 INFO [Server] Starting JBoss (MX MicroKernel)...
09:58:41,260 INFO [Server] Release ID: JBoss [WonderLand] 3.2.3 (build: CVSTag=JBoss_3_2_3 date=200311301445)
09:58:41,260 DEBUG [Server] Using config: org.jboss.system.server.ServerConfigImpl@ecd7e
09:58:41,260 DEBUG [Server] Server type: class org.jboss.system.server.ServerImpl
09:58:41,260 INFO [Server] Home Dir: C:\jboss-cluster
09:58:41,260 INFO [Server] Home URL: file:/C:/jboss-cluster/
...
===============================================================================================
== JGroups version
===============================================================================================
C:\jboss-cluster\server\backend-nodo1\lib>java -cp jgroups.jar org.jgroups.Version
Version: 2.2.0
CVS: $Id: Version.java,v 1.1.1.1 2003/09/09 01:24:08 belaban Exp $
History: (see doc/history.txt for details)
Test and demo programs works fine.
A - java org.jgroups.demos.Draw
B - java org.jgroups.tests.McastReceiverTest -mcast_addr 224.10.10.10 -port 5555
java org.jgroups.tests.McastSenderTest -mcast_addr 224.10.10.10 -port 5555
===============================================================================================
To execute the cluster on the same machine i've opportunely changed these files for each one of FE1, BE1 and BE2 nodes
/<jboss-installation-directory>/server/\conf\jboss-minimal.xml
/<jboss-installation-directory>/server/\conf\jboss-service.xml
/<jboss-installation-directory>/server/\conf\jacorb.properties
/<jboss-installation-directory>/server/\deploy\http-invoker.sar\META-INF\jboss-service.xml
/<jboss-installation-directory>/server/\deploy\jbossweb-tomcat41.sar\META-INF\jboss-service.xml
/<jboss-installation-directory>/server/\deploy\jms\oil-service.xml
/<jboss-installation-directory>/server/\deploy\jms\oil2-service.xml
/<jboss-installation-directory>/server/\deploy\jms\uil2-service.xml
/<jboss-installation-directory>/server/\deploy\snmp-adaptor.sar\managers.xml
/<jboss-installation-directory>/server/\deploy\snmp-adaptor.sar\META-INF\jboss-service.xml
/<jboss-installation-directory>/server/\deploy\cluster-service.xml
the changes was about ports numbers to avoid conflicts on the same machine IP.
===============================================================================================