Monday, August 31, 2009
Daemon Applications in J2EE
Sunday, August 30, 2009
JAAS LDAP OC4J
Saturday, August 29, 2009
Advanced XML RPC Library
Apache xml rpc is good as it relieves programmer from using xml constructs, and exposes xml rpc request/response in object oriented form. See apache project site on mappings of xml rpc constructs to different types for more details. But still a better way would be to expose xml rpc as domain objects. Similar to what JAXB does in case of domain objects based on XSDs. Since XML RPC has its own schema so a domain classe code generation tool would have to rely on xml documents or annotations instead of schema.
An example for .net is http://www.xml-rpc.net/
And for java is: http://xmlrpc.sourceforge.net/
Marquïee XML-RPC Library
Commons Apache Http Client (Disable connection pooling)
Commons Apache Http Client (Disable connection pooling)
In some cases we want to disable default connection pooling of http client e.g. in case when your application is using ThreadContextClassLoader so statically managed http connection pool will not help instead it will take the pool some time to remove its single connection because its hoping that someone else will try to reuse it. Turn-off the pool, otherwise your http Server will have more unused sockets opened than required for more duration.
Note that close() method does not close underlying http connection instead it’s responsibility of connection manager to close or reuse in releaseConnection().
Use org.apache.commons.httpclient.SimpleHttpConnectionManager which physically closes http connection on close().
HttpClient client = new HttpClient(new SimpleHttpConnectionManager(true));
Apache XML RPC
In one of my projects I used Apache commons xml rpc library. I faced some issues that I would like to discuss and provide solutions that can be helpful to others.
1- Date format which is ISO 8601 as mandated by Xml RPC Specification. But since ISO 8601 does not specify one concrete format so there are confusions in implementations by clients/servers reference http://www.cookcomputing.com/blog/archives/000009.html.
In my case xml rpc server was using yyyyMMdd'T'HH:mm:ssZ, so needed to create a CustomFormat class like:
class CustomTypeFactory extends TypeFactoryImpl {
public CustomTypeFactory(XmlRpcController pController) {
super(pController);
}
private static final String ISO_FORMAT = "yyyyMMdd'T'HH:mm:ssZ";
public TypeSerializer getSerializer(XmlRpcStreamConfig pConfig,
Object pObject) throws SAXException {
if (pObject instanceof Date) {
return new DateSerializer(new SimpleDateFormat(ISO_FORMAT));
} else {
return super.getSerializer(pConfig, pObject);
}
}
}
And on org.apache.xmlrpc.client.XmlRpcClient:
client.setTypeFactory(new CustomTypeFactory(client));
2- Various transport factories (LiteHttp, SunTransport,CommonsTransport) provided with apache xml rpc library have trade-offs. Lets read my misery story step by step:
2.1. I first used SunTransport which is the default but every other day or so I found application hanged while communicating over with xml rpc server (Ctrl+Break was not much helpful).
2.2. I then moved to LiteHttp but the same behavior continued.
2.3. I then tried CommonsTransport which used apache commons http client behind the scene. But un-understandably commons client tried reaching internet to download the xml rpc schema which was mentioned in rpc server’s response. Since server’s response was not under my control and commons client did not provide any way to disable schema validation. I had to quit.
2.4- I then went on to studying XmlRpcClient code and JDK’s default http implementation. Notably I found that in JDK 1.5 reply time out can be set on URLConnection and this feature was not present in JDK 1.4. This feature was added to avoid application hanging, while reading from sockets blocked in deadlock, which is very common in distributed environment with firewalls and network glitches etc. You would observe the same in case of JDBC API which provides similar bounded blocking I/O. XmlRpcClient was not utilizing this feature instead it had same implementation of sendRequest() in base class XmlRpcSunHttpTransport for both JDK 1.5 and 1.4. So, here you go
Override sendRequest() in org.apache.xmlrpc.client. XmlRpcSun15HttpTransportFactory and enable bounded blocking read.
public Object sendRequest(XmlRpcRequest pRequest) throws XmlRpcException {
httpConfig = (XmlRpcHttpClientConfig)pRequest.getConfig();
try {
final URLConnection c =
conn = newURLConnection(httpConfig.getServerURL());
c.setUseCaches(false);
c.setDoInput(true);
c.setDoOutput(true);
//Must be used with JDK 1.5
c.setReadTimeout(httpConfig.getReplyTimeout());
c.setConnectTimeout(httpConfig.getConnectionTimeout());
} catch (IOException e) {
throw new XmlRpcException("Failed to create URLConnection: " +
e.getMessage(), e);
}
return super.sendRequest(pRequest);
}
For new ones here is the code to use apache xml rpc as a client.
private XmlRpcClient client = new XmlRpcClient();
private XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
config.setConnectionTimeout(CONNECTION_TIMEOUT);
config.setReplyTimeout(REPLY_TIMEOUT);
config.setBasicEncoding(null); //UTF-8
config.setBasicUserName(getUser());
config.setBasicPassword(getPassword());
config.setAuthScopeRealm(getRealm());
config.setUserAgent(getUserAgent());
client.setConfig(config);
client.setTypeFactory(new CustomTypeFactory(client));