remm 2002/12/06 04:00:23 Modified: catalina/src/share/org/apache/catalina/cluster JGCluster.java JGManager.java LocalStrings.properties package.html Removed: catalina/src/share/org/apache/catalina/cluster LocalStrings_fr.properties LocalStrings_ja.properties Log: - Cleanup code before moving (part 1). Revision Changes Path 1.2 +88 -75 jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/cluster/JGCluster.java Index: JGCluster.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/cluster/JGCluster.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- JGCluster.java 5 Dec 2002 12:25:09 -0000 1.1 +++ JGCluster.java 6 Dec 2002 12:00:23 -0000 1.2 @@ -109,57 +109,67 @@ /** * Descriptive information about this component implementation. */ - private static final String info = "JavaGroupsCluster/1.0"; + protected static final String info = "JavaGroupsCluster/1.0"; + /** * Name to register for the background thread. */ - private String threadName = "JavaGroupsCluster"; + protected String threadName = "JavaGroupsCluster"; + /** * Name for logging purpose */ - private String clusterImpName = "JavaGroupsCluster"; + protected String clusterImpName = "JavaGroupsCluster"; + /** * The string manager for this package. */ - private StringManager sm = StringManager.getManager(Constants.Package); + protected StringManager sm = StringManager.getManager(Constants.Package); + /** * The background thread completion semaphore. */ - private boolean threadDone = false; + protected boolean threadDone = false; + /** * The cluster name to join */ - private String clusterName = null; + protected String clusterName = null; + /** * The Container associated with this Cluster. */ - private Container container = null; + protected Container container = null; + /** * The lifecycle event support for this component. */ - private LifecycleSupport lifecycle = new LifecycleSupport(this); + protected LifecycleSupport lifecycle = new LifecycleSupport(this); + /** * Has this component been started? */ - private boolean started = false; + protected boolean started = false; + /** * The property change support for this component. */ - private PropertyChangeSupport support = new PropertyChangeSupport(this); + protected PropertyChangeSupport support = new PropertyChangeSupport(this); + /** * The debug level for this Container */ - private int debug = 0; + protected int debug = 0; /** @@ -168,14 +178,22 @@ protected HashMap managers = new HashMap(); - //A reference to the communication channel - private JChannel mChannel = null; - //the channel configuration - private String mChannelConfig = null; - //we keep a thread to listen to the channel - private ReceiverThread mChannelListener = null; - //somehow start() gets called more than once - private boolean mChannelStarted = false; + /** + * A reference to the communication channel. + */ + protected JChannel channel = null; + + + /** + * The channel configuration. + */ + protected String protocol = null; + + + /** + * Channel listener thread. + */ + protected ReceiverThread channelListener = null; // ------------------------------------------------------------- Properties @@ -270,11 +288,9 @@ * @see <a href="www.javagroups.com">JavaGroups</a> for details */ public void setProtocol(String protocol) { - String oldProtocol = this.mChannelConfig; - this.mChannelConfig = protocol; - support.firePropertyChange("protocol", - oldProtocol, - this.mChannelConfig); + String oldProtocol = this.protocol; + this.protocol = protocol; + support.firePropertyChange("protocol", oldProtocol, this.protocol); } @@ -282,7 +298,7 @@ * Returns the protocol. */ public String getProtocol() { - return (this.mChannelConfig); + return (this.protocol); } @@ -313,11 +329,6 @@ public void send(SessionMessage msg, IpAddress dest) throws Exception { - if (!mChannelStarted) { - log.warn("Channel is not active, not sending message=" + msg); - return; - } - // Check the event type, // if it is EVT_GET_ALL_SESSION then // only send the message to the coordinator @@ -325,12 +336,12 @@ IpAddress destination = dest; if (msg.getEventType() == SessionMessage.EVT_GET_ALL_SESSIONS) { destination = - (IpAddress) mChannel.getView().getMembers().elementAt(0); + (IpAddress) channel.getView().getMembers().elementAt(0); } Message jgmsg = - new Message(destination, mChannel.getLocalAddress(), msg); - mChannel.send(jgmsg); + new Message(destination, channel.getLocalAddress(), msg); + channel.send(jgmsg); } @@ -341,7 +352,7 @@ public void receive(SessionMessage msg, IpAddress sender) { // Discard all message from ourself - if (sender.equals(mChannel.getLocalAddress())) { + if (sender.equals(channel.getLocalAddress())) { return; } @@ -403,22 +414,20 @@ public void start() throws LifecycleException { - //start the javagroups channel + if (started) + throw new LifecycleException + (sm.getString("cluster.alreadyStarted")); try { - //the channel is already running - if (mChannelStarted) - return; - - mChannel = new JChannel(mChannelConfig); - mChannelListener = new ReceiverThread(this, mChannel); - mChannel.connect("TomcatReplication"); - mChannelListener.start(); - mChannelStarted = true; - log.info("Javagroups channel started inside tomcat"); + + channel = new JChannel(protocol); + channelListener = new ReceiverThread(this, channel); + channel.connect("[TomcatSC]" + container.getName()); + channelListener.start(); + log.info(sm.getString("jgCluster.channelStartSuccess")); } catch (Exception x) { - log.error("Unable to start javagroups channel",x); + log.error(sm.getString("jgCluster.channelStartFail"), x); } } @@ -438,47 +447,51 @@ public void stop() throws LifecycleException { - mChannelStarted = false; + if (!started) + throw new IllegalStateException + (sm.getString("cluster.notStarted")); - //stop the javagroup channel + // Stop the javagroup channel try { - mChannelListener.stopRunning(); - mChannel.disconnect(); - mChannel.close(); + channelListener.stopRunning(); + channel.disconnect(); + channel.close(); } catch (Exception x) { - log.error("Unable to stop javagroups channel",x); + log.error(sm.getString("jgCluster.channelStopFail"), x); } } + // --------------------------------------------- ReceiverThread Inner Class + + /** * Thread that listens to the cluster communication channel. - * */ - private class ReceiverThread + protected class ReceiverThread extends Thread { - private JGCluster mParentCluster = null; - private JChannel mParentChannel = null; - private boolean mOkToRun = true; + protected JGCluster parentCluster = null; + protected JChannel parentChannel = null; + protected boolean running = true; public ReceiverThread(JGCluster parent, JChannel listenTo) { - mParentCluster = parent; - mParentChannel = listenTo; + parentCluster = parent; + parentChannel = listenTo; } public void stopRunning() { - mOkToRun = false; + running = false; } public void run() { - while (mOkToRun) { + while (running) { try { // Receive a message from the channel - Object obj = mParentChannel.receive(0); + Object obj = parentChannel.receive(0); // Make sure it is a data message if ((obj != null) && (obj instanceof Message)) { Message msg = (Message)obj; @@ -489,20 +502,20 @@ Object myobj = stream.readObject(); if (myobj instanceof SessionMessage) { // notify the cluster - mParentCluster.receive((SessionMessage) myobj, - (IpAddress) msg.getSrc()); + parentCluster.receive((SessionMessage) myobj, + (IpAddress) msg.getSrc()); } else { - mParentCluster.log.info - ("Received unwanted message="+obj); + parentCluster.log.info + (sm.getString + ("jgCluster.channelIncorrectMessage", obj)); } } else if (obj instanceof View) { - mParentCluster.log.info - ("Received membership message="+obj); + parentCluster.log.info + (sm.getString("jgCluster.channelNewMember", obj)); } } catch (Exception x) { - if (mChannelStarted) - mParentCluster.log.warn - ("Unable to receive JavaGroup message",x); + parentCluster.log.warn + (sm.getString("jgCluster.channelFail"), x); } } 1.3 +168 -193 jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/cluster/JGManager.java Index: JGManager.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/cluster/JGManager.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- JGManager.java 5 Dec 2002 14:05:22 -0000 1.2 +++ JGManager.java 6 Dec 2002 12:00:23 -0000 1.3 @@ -112,18 +112,17 @@ org.apache.commons.logging.LogFactory.getLog( JGManager.class ); + // ----------------------------------------------------- Instance Variables + + /** * Associated JavaGroups cluster. */ protected JGCluster cluster = null; - /** - * Constructor, just calls super() - * - */ - public JGManager() { - super(); - } + + // --------------------------------------------------------- Public Methods + /** * Set JavaGroups cluster. @@ -137,6 +136,48 @@ /** + * Construct and return a new session object, based on the default + * settings specified by this Manager's properties. The session + * id will be assigned by this method, and available via the getId() + * method of the returned session. If a new session cannot be created + * for any reason, return <code>null</code>. + * + * @exception IllegalStateException if a new session cannot be + * instantiated for any reason + */ + public Session createSession() { + //create a session and notify the other nodes in the cluster + Session session = createSession(true); + add(session); // ? + return session; + } + + + public void start() throws LifecycleException { + + super.start(); + + try { + SessionMessage msg = new SessionMessage + (container.getName(), SessionMessage.EVT_GET_ALL_SESSIONS, + null, null, null, null, null); + sendSessionEvent(msg); + } catch (Exception x) { + log.error(sm.getString("jgManager.startFail"), x); + } + + } + + + public void stop() throws LifecycleException { + super.stop(); + } + + + // ------------------------------------------------------ Protected Methods + + + /** * Get new session class to be used in the doLoad() method. */ protected StandardSession getNewSession() { @@ -145,106 +186,37 @@ /** - * Creates a HTTP session. + * Creates a HTTP session.<br> * Most of the code in here is copied from the StandardManager. * This is not pretty, yeah I know, but it was necessary since the * StandardManager had hard coded the session instantiation to the a - * StandardSession, when we actually want to instantiate a ReplicatedSession<BR> - * If the call comes from the Tomcat servlet engine, a SessionMessage goes out to the other - * nodes in the cluster that this session has been created. - * @param notify - if set to true the other nodes in the cluster will be notified. - * This flag is needed so that we can create a session before we deserialize - * a replicated one + * StandardSession, when we actually want to instantiate + * a ReplicatedSession<BR> + * If the call comes from the Tomcat servlet engine, a SessionMessage + * goes out to the other nodes in the cluster that this session + * has been created. * + * @param notify if set to true the other nodes in the cluster will + * be notified. This flag is needed so that we can create a session + * before we deserialize a replicated one * @see ReplicatedSession */ protected Session createSession(boolean notify) { - //inherited from the basic manager - if ((getMaxActiveSessions() >= 0) && - (sessions.size() >= getMaxActiveSessions())) - throw new IllegalStateException(sm.getString("standardManager.createSession.ise")); - - - // Recycle or create a Session instance - Session session = null; - //modified to make sure we only recycle sessions that are of type=ReplicatedSession - //I personally believe the VM does a much better job pooling object instances - //than the synchronized penalty gives us - synchronized (recycled) { - int size = recycled.size(); - int index = size; - if (size > 0) { - do - { - index--; - session = (Session) recycled.get(index); - recycled.remove(index); - } while ( index > 0 && (session instanceof ReplicatedSession)); - } - }//synchronized - - //set the current manager - if (session != null) - session.setManager(this); - else - session = new ReplicatedSession(this); - - // Initialize the properties of the new session and return it - session.setNew(true); - session.setValid(true); - session.setCreationTime(System.currentTimeMillis()); - session.setMaxInactiveInterval(this.maxInactiveInterval); - String sessionId = generateSessionId(); - String jvmRoute = getJvmRoute(); - // @todo Move appending of jvmRoute generateSessionId()??? - if (jvmRoute != null) { - sessionId += '.' + jvmRoute; - session.setId(sessionId); - } - /* - synchronized (sessions) { - while (sessions.get(sessionId) != null) // Guarantee uniqueness - sessionId = generateSessionId(); - } - */ - session.setId(sessionId); - - if ( notify ) - { - - log.info("Replicated Session created with ID="+session.getId()); - - //notify javagroups + Session session = super.createSession(); + + if (notify) { + log.info(sm.getString + ("jgManager.sessionCreated", session.getId())); + // Notify javagroups SessionMessage msg = new SessionMessage (container.getName(), SessionMessage.EVT_SESSION_CREATED, writeSession(session), session.getId(), null, null, null); sendSessionEvent(msg); } - return (session); - } - - - //========================================================================= - // OVERRIDE THESE METHODS TO IMPLEMENT THE REPLICATION - //========================================================================= + return (session); - /** - * Construct and return a new session object, based on the default - * settings specified by this Manager's properties. The session - * id will be assigned by this method, and available via the getId() - * method of the returned session. If a new session cannot be created - * for any reason, return <code>null</code>. - * - * @exception IllegalStateException if a new session cannot be - * instantiated for any reason - */ - public Session createSession() { - //create a session and notify the other nodes in the cluster - Session session = createSession(true); - add(session); - return session; } @@ -272,7 +244,7 @@ session_out.close(); return session_data.toByteArray(); } catch ( Exception x ) { - log.warn("Failed to serialize the session!",x); + log.warn(sm.getString("jgManager.sessionSerializationFail"), x); } finally { Thread.currentThread().setContextClassLoader(oldCtxClassLoader); } @@ -303,7 +275,7 @@ ((ReplicatedSession)session).readObjectData(session_in); return session; } catch (Exception x) { - log.warn("Failed to deserialize the session!",x); + log.warn(sm.getString("jgManager.sessionDeserializationFail"), x); } finally { Thread.currentThread().setContextClassLoader(oldCtxClassLoader); } @@ -311,27 +283,6 @@ } - public void start() throws LifecycleException { - - super.start(); - - try { - SessionMessage msg = new SessionMessage - (container.getName(), SessionMessage.EVT_GET_ALL_SESSIONS, - null, null, null, null, null); - sendSessionEvent(msg); - } catch (Exception x) { - log.error("Unable to start manager", x); - } - - } - - - public void stop() throws LifecycleException { - super.stop(); - } - - protected void sendSessionEvent(SessionMessage msg) { sendSessionEvent(msg, null); } @@ -340,8 +291,8 @@ protected void sendSessionEvent( SessionMessage msg, IpAddress dest ) { try { cluster.send(msg, dest); - } catch ( Exception x ) { - log.error("Unable to send message through javagroups channel",x); + } catch (Exception x) { + log.error(sm.getString("jgManager.messageSendFail"), x); } } @@ -355,105 +306,125 @@ * EVT_GET_ALL_SESSION message, so that we only reply to * the requesting node */ - public void messageReceived( SessionMessage msg, IpAddress sender ) - { - try - { - log.debug("Received SessionMessage of type="+msg.getEventTypeString()); + public void messageReceived(SessionMessage msg, IpAddress sender) { + + try { + + if (log.isDebugEnabled()) { + log.debug(sm.getString("jgManager.messageType", + msg.getEventTypeString())); + } - switch ( msg.getEventType() ) - { + switch (msg.getEventType()) { + case SessionMessage.EVT_ATTRIBUTE_ADDED: { - //add the attribute to the replicated session - ReplicatedSession session = (ReplicatedSession)findSession(msg.getSessionID()); - if ( session == null ) { - log.warn("Replicated session with ID{1} ["+msg.getSessionID() + "] doesn't exist!"); + // Add the attribute to the replicated session + ReplicatedSession session = + (ReplicatedSession) findSession(msg.getSessionID()); + if (session == null) { + log.warn(sm.getString("jgManager.unknownSessionID", + msg.getSessionID())); return; - }//end if - //log("Attribute added to session="+msg.getSessionID()+ " will be inserted into session="+session); - //how does the call below affect session binding listeners? - session.setAttribute(msg.getAttributeName(),msg.getAttributeValue(),false); + } + // FIXME + // How does the call below affect session binding listeners + session.setAttribute + (msg.getAttributeName(),msg.getAttributeValue(),false); break; } case SessionMessage.EVT_ATTRIBUTE_REMOVED_WNOTIFY: case SessionMessage.EVT_ATTRIBUTE_REMOVED_WONOTIFY: { - boolean notify = (msg.getEventType() == SessionMessage.EVT_ATTRIBUTE_REMOVED_WNOTIFY); - //remove the attribute from the session - ReplicatedSession session = (ReplicatedSession)findSession(msg.getSessionID()); - if ( session == null ) { - log.warn("Replicated session with ID{2} ["+msg.getSessionID() + "] doesn't exist!"); + boolean notify = + (msg.getEventType() + == SessionMessage.EVT_ATTRIBUTE_REMOVED_WNOTIFY); + // Remove the attribute from the session + ReplicatedSession session = + (ReplicatedSession) findSession(msg.getSessionID()); + if (session == null) { + log.warn(sm.getString("jgManager.unknownSessionID", + msg.getSessionID())); return; - }//end if - //how does this affect the listeners? - session.removeAttribute(msg.getAttributeName(),notify,false); + } + // How does this affect the listeners? + session.removeAttribute + (msg.getAttributeName(), notify, false); break; } case SessionMessage.EVT_REMOVE_SESSION_NOTE: { - //remove the note from the session - ReplicatedSession session = (ReplicatedSession)findSession(msg.getSessionID()); - if ( session == null ) { - log.warn("Replicated session with ID{3} ["+msg.getSessionID() + "] doesn't exist!"); + // Remove the note from the session + ReplicatedSession session = + (ReplicatedSession) findSession(msg.getSessionID()); + if (session == null) { + log.warn(sm.getString("jgManager.unknownSessionID", + msg.getSessionID())); return; - }//end if - //how does this affect the listeners? + } + // How does this affect the listeners? session.removeNote(msg.getAttributeName(),false); break; } case SessionMessage.EVT_SET_SESSION_NOTE: { - //add the note to the session - ReplicatedSession session = (ReplicatedSession)findSession(msg.getSessionID()); - if ( session == null ) { - log.warn("Replicated session with ID{4} ["+msg.getSessionID() + "] doesn't exist!"); + // Add the note to the session + ReplicatedSession session = + (ReplicatedSession) findSession(msg.getSessionID()); + if (session == null) { + log.warn(sm.getString("jgManager.unknownSessionID", + msg.getSessionID())); return; - }//end if - //how does this affect the listeners? - session.setNote(msg.getAttributeName(),msg.getAttributeValue(),false); + } + // How does this affect the listeners? + session.setNote(msg.getAttributeName(), + msg.getAttributeValue(), false); break; } case SessionMessage.EVT_GET_ALL_SESSIONS: { - //get a list of all the session from this manager + // Get a list of all the session from this manager Object[] sessions = findSessions(); - for (int i=0; i<sessions.length; i++) - { - //make sure we only replicate sessions - //that are replicatable :) - if ( sessions[i] instanceof ReplicatedSession) - { - ReplicatedSession ses = (ReplicatedSession)sessions[i]; + for (int i=0; i<sessions.length; i++) { + // Make sure we only replicate sessions + // that are replicatable :) + if (sessions[i] instanceof ReplicatedSession) { + ReplicatedSession ses = + (ReplicatedSession) sessions[i]; SessionMessage newmsg = new SessionMessage (container.getName(), SessionMessage.EVT_SESSION_CREATED, writeSession(ses), ses.getId(), null, null, null); sendSessionEvent(newmsg,sender); - //since the principal doesn't get serialized, we better send it over too - if ( ses.getPrincipal() != null ) - { + // Since the principal doesn't get serialized, + // we better send it over too + if (ses.getPrincipal() != null) { SessionMessage pmsg = new SessionMessage (container.getName(), SessionMessage.EVT_SET_USER_PRINCIPAL, null, ses.getId(), null, null, SerializablePrincipal.createPrincipal - ((GenericPrincipal)ses.getPrincipal())); + ((GenericPrincipal) ses.getPrincipal())); sendSessionEvent(pmsg,sender); } + } else { + log.warn(sm.getString + ("jgManager.nonStandardSession", + sessions[i])); } - else log.warn("System contains non standard sessions="+sessions[i]); } break; } case SessionMessage.EVT_SESSION_ACCESSED: { - //this is so that the replicated session doesn't expire in any - //other node - ReplicatedSession session = (ReplicatedSession)findSession(msg.getSessionID()); - if ( session == null ) { - log.warn("Replicated session with ID{5} ["+msg.getSessionID() + "] doesn't exist!"); + // This is so that the replicated session doesn't expire + // in any other node + ReplicatedSession session = + (ReplicatedSession) findSession(msg.getSessionID()); + if (session == null) { + log.warn(sm.getString("jgManager.unknownSessionID", + msg.getSessionID())); return; } session.access(false); @@ -461,20 +432,22 @@ } case SessionMessage.EVT_SET_USER_PRINCIPAL: { - //set the user principal - ReplicatedSession session = (ReplicatedSession)findSession(msg.getSessionID()); - if ( session == null ) { - log.warn("Replicated session with ID{6} ["+msg.getSessionID() + "] doesn't exist!"); + // Set the user principal + ReplicatedSession session = + (ReplicatedSession) findSession(msg.getSessionID()); + if (session == null) { + log.warn(sm.getString("jgManager.unknownSessionID", + msg.getSessionID())); return; } - //log("Setting principal for the session"); - GenericPrincipal principal = (msg.getPrincipal()).getPrincipal(getContainer().getRealm()); - session.setPrincipal(principal,false); + GenericPrincipal principal = + (msg.getPrincipal()).getPrincipal + (getContainer().getRealm()); + session.setPrincipal(principal, false); break; } case SessionMessage.EVT_SESSION_CREATED: { - //log("Session got replicated="+msg.getSessionID()); Session session = this.readSession(msg.getSession()); session.setManager(this); add(session); @@ -483,11 +456,15 @@ case SessionMessage.EVT_SESSION_EXPIRED_WNOTIFY: case SessionMessage.EVT_SESSION_EXPIRED_WONOTIFY: { - //session has expired - boolean notify = msg.getEventType() == SessionMessage.EVT_SESSION_EXPIRED_WNOTIFY; - ReplicatedSession session = (ReplicatedSession)findSession(msg.getSessionID()); - if ( session == null ) { - log.warn("Replicated session with ID{7} ["+msg.getSessionID() + "] doesn't exist!"); + // Session has expired + boolean notify = + (msg.getEventType() + == SessionMessage.EVT_SESSION_EXPIRED_WNOTIFY); + ReplicatedSession session = + (ReplicatedSession) findSession(msg.getSessionID()); + if (session == null) { + log.warn(sm.getString("jgManager.unknownSessionID", + msg.getSessionID())); return; } session.expire(notify, false); @@ -495,14 +472,12 @@ } default: { - //we didn't recognize the message type, do nothing + // We didn't recognize the message type, do nothing break; } - }//switch - } - catch ( Exception x ) - { - log.error("Unable to receive message through javagroups channel", x); + } + } catch (Exception x) { + log.error(sm.getString("jgManager.messageReceiveFail", x)); } } 1.2 +1 -11 jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/cluster/LocalStrings.properties Index: LocalStrings.properties =================================================================== RCS file: /home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/cluster/LocalStrings.properties,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- LocalStrings.properties 18 Jul 2002 16:48:13 -0000 1.1 +++ LocalStrings.properties 6 Dec 2002 12:00:23 -0000 1.2 @@ -1,11 +1 @@ -standardCluster.alreadyStarted=Cluster has already been started -standardCluster.notStarted=Cluster has not yet been started -standardCluster.socketOrAddressNull=multicastSocket || multicastAddress can't be null -standardCluster.joinGroup=Joining group {0} -standardCluster.leaveGroup=Leaving group {0} -standardCluster.createReceiver=Creating a new receiver for {0} -standardCluster.createSender=Creating a new sender for {0} -standardCluster.invalidAddress=Invalid multicastAddress {0} -standardCluster.joinException=An error occurred when trying to join group {0} -standardCluster.leaveException=An error occurred when trying to leave group {0} -multicastSender.sendException=An error occurred when trying to replicate {0} \ No newline at end of file + 1.2 +2 -15 jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/cluster/package.html Index: package.html =================================================================== RCS file: /home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/cluster/package.html,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- package.html 18 Jul 2002 16:48:13 -0000 1.1 +++ package.html 6 Dec 2002 12:00:23 -0000 1.2 @@ -4,21 +4,8 @@ of a Cluster is <code>org.apache.catalina.Cluster</code> implementations of this class is done when implementing a new Cluster protocol</p> -<p>The only Cluster protocol currently implemented is a MulticastProtocol<br> - <b>StandardCluster.java</b> +<p>The only Cluster protocol currently implemented is a JavaGroups based<br> + <b>JGCluster.java</b> </p> - -<p>In addition to the <code>Cluster</code> implementation -<code>StandardCluster</code> there's a listener and a sender implemented -using multicasting. -<ul> -<li><b>MulticastSender</b> - A <code>ClusterSender</code> implementation that works -with a MulticastSocket</li> -<li><b>MulticastReceiver</b> - A <code>ClusterReceiver</code> implementation that works -with a MulticastSocket</li> -</ul> - -<p>Both extend the common class <code>ClusterSessionBase</code> which provides common -functionality shared by the two implementations.</p> </body>
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>