0 Replies Latest reply on Apr 5, 2004 5:51 AM by marcoantonioni

    SFSB prolem during state replication in HA cluster (3) ? (so

      <<< 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.
      ===============================================================================================