Hi
Marcin,
I had a similar problem with xmlrpc, no way to set
the timeout, so I wrote a utility class to add this. The other thing I
wanted was for any exceptions that were caught in the thread that actually
performs the xmlrpc.execute to be passed to the object that created the thread,
and then rethrown. I don't know if there was an easier way to do this, but it
seems to work OK. I've been using this in production on several
projects with no major problems so far.
Code follows... forgive the lack of docco
:)
Regards
Jason
--
Falun Gong: A peaceful meditation practice under persecution in China
http://www.falundafa.org
Falun Gong: A peaceful meditation practice under persecution in China
http://www.falundafa.org
Truth - Compassion - Forbearance
package
common.util.xmlrpc;
/**
* <p>Title: TimedXmlRpcClient</p>
* <p>Description: This XmlRpcClient simply adds a connection timeout, after
* which if the XML-RPC call did not complete, an IOException is thrown.</p>
* <p>Copyright: Copyright (c) 2002</p>
* <p>Company: </p>
* <p>Title: TimedXmlRpcClient</p>
* <p>Description: This XmlRpcClient simply adds a connection timeout, after
* which if the XML-RPC call did not complete, an IOException is thrown.</p>
* <p>Copyright: Copyright (c) 2002</p>
* <p>Company: </p>
* @author Jason Wyatt
* @version 1.0
*/
* @version 1.0
*/
import java.util.Vector;
import java.io.IOException;
import java.net.MalformedURLException;
import
org.apache.xmlrpc.*;
public class TimedXmlRpcClient
implements Runnable
{
private XmlRpcClient xmlRpcClient;
private String hostname;
private int ip;
private int connectTimeout=30000; // 30 seconds default
private String remoteFunction;
private Vector params;
private Object returnValue=null;
private XmlRpcException xmlRpcException=null;
private IOException ioException=null;
private MalformedURLException malformedURLException=null;
{
private XmlRpcClient xmlRpcClient;
private String hostname;
private int ip;
private int connectTimeout=30000; // 30 seconds default
private String remoteFunction;
private Vector params;
private Object returnValue=null;
private XmlRpcException xmlRpcException=null;
private IOException ioException=null;
private MalformedURLException malformedURLException=null;
TimedXmlRpcClient(String
hostname, int ip, int connectTimeout, String remoteFunction, Vector
params)
{
this.hostname=hostname;
this.ip=ip;
this.connectTimeout=connectTimeout;
this.remoteFunction=remoteFunction;
this.params=params;
}
{
this.hostname=hostname;
this.ip=ip;
this.connectTimeout=connectTimeout;
this.remoteFunction=remoteFunction;
this.params=params;
}
public static Object execute(String
hostname, int ip, int connectTimeout, String remoteFunction, Vector params)
throws XmlRpcException,
IOException, MalformedURLException
{
TimedXmlRpcClient client=new TimedXmlRpcClient(hostname,ip,connectTimeout,remoteFunction,params);
IOException, MalformedURLException
{
TimedXmlRpcClient client=new TimedXmlRpcClient(hostname,ip,connectTimeout,remoteFunction,params);
Thread t = new
Thread(client);
t.start();
try
{
t.join(connectTimeout); // exit the thread once it has completed, or after timeout
}
catch (InterruptedException ex)
{
}
t.start();
try
{
t.join(connectTimeout); // exit the thread once it has completed, or after timeout
}
catch (InterruptedException ex)
{
}
// if an exception
occurred while executing the remote call, throw it again
// from here
IOException ex=client.getIOException();
if(ex!=null)
throw ex;
// from here
IOException ex=client.getIOException();
if(ex!=null)
throw ex;
XmlRpcException
ex2=client.getXmlRpcException();
if(ex2!=null)
throw ex2;
if(ex2!=null)
throw ex2;
MalformedURLException
ex3=client.getMalformedURLException();
if(ex3!=null)
throw ex3;
if(ex3!=null)
throw ex3;
Object
returnVal=client.getReturnVal();
if(returnVal==null)
throw new IOException("Operation timed out");
if(returnVal==null)
throw new IOException("Operation timed out");
return
returnVal;
}
}
public void run()
{
try
{
xmlRpcClient=new XmlRpcClient(hostname, ip);
returnValue=xmlRpcClient.execute(remoteFunction, params);
}
catch (MalformedURLException ex)
{
malformedURLException=ex;
}
catch (IOException ex2)
{
ioException=ex2;
}
catch(XmlRpcException ex3)
{
xmlRpcException=ex3;
}
}
{
try
{
xmlRpcClient=new XmlRpcClient(hostname, ip);
returnValue=xmlRpcClient.execute(remoteFunction, params);
}
catch (MalformedURLException ex)
{
malformedURLException=ex;
}
catch (IOException ex2)
{
ioException=ex2;
}
catch(XmlRpcException ex3)
{
xmlRpcException=ex3;
}
}
public Object
getReturnVal()
{
return returnValue;
}
{
return returnValue;
}
public XmlRpcException
getXmlRpcException()
{
return xmlRpcException;
}
{
return xmlRpcException;
}
public IOException
getIOException()
{
return ioException;
}
{
return ioException;
}
public MalformedURLException
getMalformedURLException()
{
return malformedURLException;
}
{
return malformedURLException;
}
public static void main(String[] args)
{
try
{
Vector params=new Vector();
params.add( "select table_name from all_tables");
TimedXmlRpcClient.execute("localhost",32000,5,"queryHandler.sqlQuery",params);
}
catch (Exception ex)
{
System.err.println("Error calling TimedXmlRpcClient:");
ex.printStackTrace();
}
}
}
From: Marcin Skladaniec [mailto:[EMAIL PROTECTED]
Sent: Wednesday, 13 October 2004 4:02 PM
To: [EMAIL PROTECTED]
Subject: XmlRpc Client won't die ...
I have a XmlRpcClient executing an rpc method on very unreliable server. I have to force quit XmlRpcClient.execute() from time to time, but I can't. I have even created a separate Thread for it, and I'm quitting the Thread after timeout. It is working but not always, when server receives xmlrpc request and freezes without any sign of life my thread is uninterruptible. Is my approach to this problem right or am I missing something ? Does anyone created some other workaround for missing timeout in XmlRpc framework ?
This is the impoortant part of my code:
public/color> SpacialThread(String pRemoteDatabaseURL, String pXmlRpcMethod, Vector pXmlRpcParameters) {
super/color>();
xmlRpcResponse = null/color>;
xmlRpcMethod = pXmlRpcMethod;
xmlRpcParameters = pXmlRpcParameters;
// See setResponse/color>
hasReceivedResponse = false/color>;
hasBeenInterrupted = false/color>;
try/color> {
client = new/color> XmlRpcClient(pRemoteDatabaseURL);
} catch/color> (java.net.MalformedURLException e) {
logger.error("(hash: "/color> + hashCode() + "): java.net.MalformedURLException thrown:\n"/color>
+ e);
}
start();
}
public/color> void/color> run() {
try/color> {
// This is a blocking call.../color>
logger.debug("(hash: "/color> + hashCode() + "): Attempting Xml Rpc transaction."/color>);
// Set response explicitly (this should be thread safe?)/color>
Object response = client.execute(xmlRpcMethod, xmlRpcParameters);
setResponse(response);
if/color> (isInterrupted()) {
hasBeenInterrupted = true/color>;
logger.error("(hash: "/color> + hashCode() + "): Xml Rpc transaction interrupted explicitly. Exiting. (Communication with remote abandoned)"/color>);
} else/color> {
logger.debug("(hash: "/color> + hashCode() + "): Returned from Xml Rpc transaction."/color>);
}
} catch/color> (Exception e) {
// Something else gone wrong... log the error and leave the exception for reference./color>
logger.error("(hash: "/color> + hashCode() + "): Xml Rpc transaction interrupted abormally. Exiting. (Communication with remote abandoned)"/color>);
setException(e);
} finally/color> {
// Regardless of the situation, clean up and release the network resources (hopefully)/color>
logger.debug("(hash: "/color> + hashCode() + "): Xml Rpc transaction finilizing - releasing resources."/color>);
client = null/color>;
}
}
Cheers
Marcin Skladaniec
