The situation is like this:
I use Axis2 1.6.2 and I have generated Stubs (with wsdl2java) for 2 Web services - lets call them WS#1 and WS#2.
I use a pooling mechanism for the Stubs by implementing a StubPoolableFactory which extends BasePoolableObjectFactory (org.apache.commons.pool.BasePoolableObjectFactory)
In order to achieve this, the Stubs are "wrapped" by Adapters made as Singletons. A skeleton of an Adapter is like the following:
/** The Adapter class */
public class PdfServiceAdapter extends PoolableStubAdapter<PdfServiceStub> {
/** The Singleton. */
private static PdfServiceAdapter pdfServiceAdapter;
/**
* Gets the PdfService adapter instance.
*
* @return the PdfService adapter
*/
public synchronized static PdfServiceAdapter getPdfServiceAdapter() {
if (null == pdfServiceAdapter) {
pdfServiceAdapter = new PdfServiceAdapter();
pdfServiceAdapter.initiateStubPool();
}
return pdfServiceAdapter;
}
public void doSomething() throws AdapterException {
try {
stub = getStub();
} catch (final Exception e) {
throw new AdapterPreparationException(e);
}
try {
//call some actual Stub method here...
} catch (final Exception e) {
stopWatch.stop("PdfService.doSomething.FAILURE");
throw new AdapterExecutionException(e);
} finally {
final ServiceClient client = stub._getServiceClient();
if (client != null) {
try {
client.cleanupTransport();
client.cleanup();
} catch (final AxisFault e) {
log.warn("Something went wrong while cleaning up service client: ", e);
}
}
releaseStub(stub);
}
}
@Override
protected int getMaxActive() {
return Integer.parseInt(ESignatureConfig.getInstance().getConfig().getString(
"AXIS_STUB_POOL_EREQUEST_COMMUNICATION_MAX_ACTIVE"));
}
@Override
protected boolean getLifo() {
return Boolean.parseBoolean(ESignatureConfig.getInstance().getConfig().getString(
"AXIS_STUB_POOL_EREQUEST_COMMUNICATION_LIFO_FLAG"));
}
@Override
protected int getMaxIdle() {
return Integer.parseInt(ESignatureConfig.getInstance().getConfig().getString(
"AXIS_STUB_POOL_EREQUEST_COMMUNICATION_MAX_IDLE"));
}
@Override
protected long getMaxWait() {
return Integer.parseInt(ESignatureConfig.getInstance().getConfig().getString(
"AXIS_STUB_POOL_EREQUEST_COMMUNICATION_MAX_WAIT"));
}
@Override
protected String getEndPointURL() {
return ESignatureConfig.getInstance().getConfig().getString("PDF_SERVICE_ENDPONT");
}
@Override
protected Stub getInstance() throws Exception {
return new PdfServiceStub(AxisConfigurationContextFactory.getInstance().getConfigurationContext());
}
}
As you can see when you request for an Instance of a Stub, an Axis Configuration is passed to the Stub. This Axis Configuration is returned from a factory, it is a Singleton and is based on MultiThreadedHttpConnectionManager with cached HTTP client.
Now, where the problem lies:
- Sometimes and usually after having long time to call a Web service, if we call WS#1 and right after WS#2, there is a Connection Reset error when calling WS#2. If after this connection reset we call again WS#1 and WS#2 right after once more then, no problem.
- Also, we have no problems when stress-testing the application. Only when we let it idle and only when calling "back 2 back" WS#1 and WS#2 always the connection reset happens on the WS#2 call.
Do you think this has to do with my implementation? Maybe the Singleton Axis Configuration or the cached HTTP client under some circustances are responsible for this reset?