📄 rmijmsconnectionstub.java
字号:
/**
* Redistribution and use of this software and associated documentation
* ("Software"), with or without modification, are permitted provided
* that the following conditions are met:
*
* 1. Redistributions of source code must retain copyright
* statements and notices. Redistributions must also contain a
* copy of this document.
*
* 2. Redistributions in binary form must reproduce the
* above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. The name "Exolab" must not be used to endorse or promote
* products derived from this Software without prior written
* permission of Exoffice Technologies. For written permission,
* please contact info@exolab.org.
*
* 4. Products derived from this Software may not be called "Exolab"
* nor may "Exolab" appear in their names without prior written
* permission of Exoffice Technologies. Exolab is a registered
* trademark of Exoffice Technologies.
*
* 5. Due credit should be given to the Exolab Project
* (http://www.exolab.org/).
*
* THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
* NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Copyright 2000-2003 (C) Exoffice Technologies Inc. All Rights Reserved.
*
* $Id: RmiJmsConnectionStub.java,v 1.20 2003/08/07 13:32:54 tanderson Exp $
*
* Date Author Changes
* 04/12/2000 jima Created
*/
package org.exolab.jms.client.rmi;
import java.rmi.ConnectException;
import java.rmi.RemoteException;
import javax.jms.JMSException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.exolab.jms.client.JmsConnectionStubIfc;
import org.exolab.jms.client.JmsErrorCodes;
import org.exolab.jms.client.JmsSessionStubIfc;
import org.exolab.jms.server.rmi.RemoteJmsServerConnectionIfc;
import org.exolab.jms.server.rmi.RemoteJmsServerSessionIfc;
/**
* This class is repsonsible for returning a reference to a remote JMS
* connection. If it cannot access get a remote connection then the constructor
* will fail with a JMSException
*
* @version $Revision: 1.20 $ $Date: 2003/08/07 13:32:54 $
* @author <a href="mailto:jima@exoffice.com">Jim Alateras</a>
*/
public class RmiJmsConnectionStub
implements JmsConnectionStubIfc {
/**
* This is a reference to the remote connection stub that is constructed
* during object initialisation.
*/
protected volatile RemoteJmsServerConnectionIfc _delegate = null;
/**
* This is a reference to the server stub that created this connection
*/
protected RmiJmsServerStub _owner = null;
/**
* Cache a reference to the pinging thread. This thread is used to
* determine whether the server is still active
*/
private PingThread _pinger = null;
/**
* System property to override the max retries for failed rmi requests.
* The default is 10
*/
public final String MAX_RETRY_PROP = "org.exolab.jms.rmi.retryCount";
/**
* System property, which specifies the interval between successive
* retries.
* The value is specified in milliseconds and defaults to 100ms
*/
public final String RETRY_INTERVAL_PROP =
"org.exolab.jms.rmi.retryInterval";
/**
* The logger
*/
private static final Log _log =
LogFactory.getLog(RmiJmsConnectionStub.class);
/**
* Instantiate an instance of this class with the specified remote object.
* This object is a delegate for all other requests. If a null connection
* is specified then throw a JMSException exception
*
* @param RemoteJmsServerConnectionIfc
* @param pingInterval interval between client pings
* @param server the server creating the connection
* @throws JMSException
*/
public RmiJmsConnectionStub(RemoteJmsServerConnectionIfc connection,
int pingInterval, RmiJmsServerStub server)
throws JMSException {
if (connection != null) {
_owner = server;
_delegate = connection;
// this is used to determine whether or not the server is
// active
if (pingInterval > 0) {
(_pinger = new PingThread(pingInterval)).start();
}
} else {
throw new JMSException("Cannot instantiate with a null " +
"connection");
}
}
// implementation of JmsConnectionStubIfc.createSession
public JmsSessionStubIfc createSession(int ackMode, boolean transacted)
throws JMSException {
RmiJmsSessionStub stub = null;
try {
RemoteJmsServerSessionIfc session = _delegate.createSession(
ackMode, transacted);
stub = new RmiJmsSessionStub(session);
session.setMessageListener(stub);
} catch (RemoteException exception) {
// rethrow as a JMSException
throw new JMSException("Failed to createSession " + exception);
}
return stub;
}
// implementation of JmsConnectionStubIfc.close
public void close() throws JMSException {
// stop the pinging thread
if (_pinger != null) {
_pinger.close();
}
// close the delegate
try {
_delegate.close();
_delegate = null;
} catch (RemoteException exception) {
// rethrow as a JMSException
throw new JMSException("Failed to close " + exception);
}
}
// implementation of JmsConnectionStubIfc.getConnectionId
public String getConnectionId() throws JMSException {
try {
return _delegate.getConnectionId();
} catch (RemoteException exception) {
// rethrow as a JMSException
throw new JMSException("Failed to getConnectionId " + exception);
}
}
// implementation of JmsConnectionStubIfc.destroy
public void destroy() {
if (_pinger != null) {
_pinger.close();
}
_delegate = null;
_owner = null;
}
/**
* This thread is used to send ping requests to the server. The server uses
* these requests to determine whether a client has disconnected.
* The frequency of these requests is determined by the server.
*/
private class PingThread extends Thread {
/**
* Maintains the interval at which ping requests are generated to the
* server. The value is in seconds
*/
private int _interval;
/**
* The maximum no. of times to retry failed pings
*/
private int _retries;
/**
* The interval between retrying failed pings
*/
private int _retryInterval;
/**
* Determines if the thread should stop
*/
private volatile boolean _stop = false;
/**
* Instantiate a daemon thread that will be used to periodically send
* ping requests to the server at the specified interval
*
* @param interval the interval between ping requests in seconds
*/
PingThread(int interval) {
_interval = interval;
setName("PingThread-" + Math.abs(hashCode()));
setDaemon(true);
_retries = getProperty(MAX_RETRY_PROP, 10, 1);
_retryInterval = getProperty(RETRY_INTERVAL_PROP, 100, 100);
}
/**
* This will run forever generating ping requests to the clients
*/
public void run() {
while (!_stop) {
if (ping()) {
// sleep for the specified interval
try {
Thread.currentThread().sleep(_interval * 1000);
} catch (InterruptedException ignore) {
}
} else {
// the server is no longer available so notify the
// client
try {
JMSException error = new JMSException(
"Connection to server terminated",
JmsErrorCodes.CONNECTION_TO_SERVER_DROPPED);
_log.warn("Server is not responding. "
+ "Generating onException",
error);
_owner.getExceptionListener().onException(error);
} catch (Throwable ignore) {
}
break;
}
}
}
public void close() {
_stop = true;
try {
interrupt();
} catch (SecurityException ignore) {
}
}
private boolean ping() {
boolean successful = false;
// send the ping request. We need to wrap this up in a
// retry loop to cater for a ConnectException that happens
// when the server is busy or out of resources.
RemoteJmsServerConnectionIfc delegate = _delegate;
if (delegate != null) {
int count = 0;
while ((count < _retries) && !successful && !_stop) {
try {
delegate.ping();
successful = true;
} catch (RemoteException exception) {
_log.warn("Failed to ping openjms server. "
+ "Retry count=" + count, exception);
if ((exception.detail instanceof ConnectException) &&
(count < _retries - 1)) {
// underlying exception is connection
// related...let's retry the request after sleeping
try {
Thread.sleep(_retryInterval);
} catch (InterruptedException ignore) {
}
}
} catch (Throwable exception) {
// print the exception but continue
_log.warn("Exception pinging server", exception);
}
++count;
}
}
return successful;
}
private int getProperty(String name, int defaultValue, int minimum) {
int result = defaultValue;
String value = null;
try {
value = System.getProperty(name);
} catch (SecurityException ignore) {
}
if (value != null) {
try {
result = Integer.parseInt(value);
if (result <= minimum) {
result = minimum;
}
} catch (NumberFormatException ignore) {
// keep the default
}
}
return result;
}
} //-- PingThread
} //-- RmiJmsConnectionStub
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -