Dear reader,
While working with Apache HttpClient you may face this error:
java.lang.IllegalArgumentException: host parameter is null
at org.apache.commons.httpclient.HttpConnection.<init>(HttpConnection.java:206)
at org.apache.commons.httpclient.HttpConnection.<init>(HttpConnection.java:155)
at org.apache.commons.httpclient.SimpleHttpConnectionManager.getConnectionWithTimeout(SimpleHttpConnectionManager.java:175)
at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:153)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323)
This comes in a multi-threaded stress test, when under heavy load concurrently opening many HttpClient connections,
intermittently receives an IllegalArgumentException with the following stack trace:
java.lang.IllegalArgumentException: host parameter is null
at org.apache.commons.httpclient.HttpConnection.<init>(HttpConnection.java:206)
at org.apache.commons.httpclient.HttpConnection.<init>(HttpConnection.java:155)
at org.apache.commons.httpclient.SimpleHttpConnectionManager.getConnectionWithTimeout(SimpleHttpConnectionManager.java:175)
at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:153)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323)
Again, this issue comes only intermittently under heavy connect load. There appears some sort of timing-related error in HttpClient.
This comes in a “multi threaded environment when there are too many instances of HttpClient” created and system is not able to resolve HostName quickly.
Solution: Set explicitly the HostConfiguration before creating the GetMethod:
PostMethod method = null;
HttpClient httpclient = new HttpClient();
String theURL = YOUR_PREPARED_URL;
HostConfiguration hf=new HostConfiguration();
hf.setHost("http://localhost", 22);
method = new PostMethod(theURL);
method.setHostConfiguration(hf);
LogHelper.logMessage("Before sending SMS Message: "+message);
int respCode = httpclient.executeMethod(method);
System.out.println("Response code:"+respCode); //200 means successful.
So far this will eliminate this intermittent failure.
//Code is tested and works fine..
Tuesday, May 31, 2011
java.lang.IllegalArgumentException: host parameter is null
Singleton pattern and Volatile in java
Dear reader,
Here is the complete example with test cases of Singleton Pattern in java.
Conditions of Singleton pattern:
1) One and only one instance of that Class.
2) Can't be cloned as cloning creates a new object violating Design principles of SingletonPattern.
3) Any sub-class of Singleton class should not be allowed as there is a default constructor in Sub-class
and using that multiple objects can be created. So Singleton class should have private default
constructor to avoid getting invoked using super() from sub-class constructor.
4) Make instance variable as Volatile. volatile ensures that multiple threads handle the object correctly
when it is being initialized in the SingletonPattern. For more details about "volatile", please see
at the end of this article.
5) Also, it should be designed in such a way that even after De-Serialization too, same object should be
returned. As making serialization and de-serialization multiple instances can be created. I have given
an example for this too.
//Full example (SingletonPattern.java)
public class SingletonPattern {
private volatile static SingletonPattern object=null;
private SingletonPattern(){} //No subclass can be created because of this private default constructor.
public static SingletonPattern getInstance(){ //Never put synchronized in method, else other threads will be
//blocked for getting object.
if(object==null){ //Check instance, if there isn't one, enter a synchronized block.
synchronized (SingletonPattern.class) { //We only synchronized the first time through.
if(object==null){ //Once in the block, double check for null and create an instance.
object=new SingletonPattern();
}
}
}
return object;
}
public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException("Cloning of this class is not allowed");
}
}
//Main test class (SingletonMain.java)
================Tries to extend SingletonClass: Prohibited================
/*public class SingletonMain extends SingletonPattern {
public SingletonMain(){} //Not allowed, as super class constructor is private.
public static void main(String[] args) {
SingletonPattern obj=SingletonPattern.getInstance();
System.out.println(obj);
}
}
*/
/*public class SingletonMain extends SingletonPattern { //Not allowed as it assumes a default constructor
//Constructor code is not written here. //should be there in super class.
public static void main(String[] args) {
SingletonPattern obj=SingletonPattern.getInstance();
System.out.println(obj);
}
}
*/
================Tries to clone SingletonClass: Prohibited================
//Now your class need to implement Cloneable Interface and then only use the below
//code, else it will throw exception. Because if a class doesn't implement Cloneable,
//it can't be cloned.
public class SingletonMain implements Cloneable {
public static void main(String[] args) throws Exception {
SingletonPattern obj=SingletonPattern.getInstance();
System.out.println(obj);
SingletonPattern main=(SingletonPattern)(obj.clone()); //Will throw exception, cloning is prohibited.
System.out.println(main);
}
}
//Output when run SingletonMain class
SingletonPattern@360be0
Exception in thread "main" java.lang.CloneNotSupportedException: Cloning of this class is not allowed
at SingletonPattern.clone(SingletonPattern.java:17)
at SingletonMain.main(SingletonMain.java:25)
============================volatile===========================
Making instance volatile ensures that mulitple threads handle the object correctly when it is being
initialized to the SingletonPattern class.
To Understand example of volatile keyword in java let’s go back to Singleton pattern in Java and see
double checked locking in Singleton with Volatile and without volatile keyword in java.
------------------
//This example is representation of Singleton Pattern discussed above
public class SingletonPattern {
private static volatile SingletonPattern _instance;
public static SingletonPattern getInstance() {
if(_instance == null){
synchronized(SingletonPattern.class){
if(_instance == null)
_instance = new SingletonPattern();
}
}
return _instance;
}
}
------------------
If you look at the code carefully you will be able to figure out:
1) We are only creating instance one time
2) We are creating instance lazily at the time of first request comes.
If we do not make _instance variable volatile then Thread which is creating _instance of SingletonPattern is
not able to communicate other thread, that instance has been created until it comes out of the SingletonPattern
block, so if Thread A is creating SingletonPattern instance and just after creation lost the CPU, all other
threads will not be able to see value of "_instance" as not null and they will believe its still null.
Why because reader threads are not doing any locking and until writer thread comes out of synchronized
block, memory will not be synchronized and value of _instance will not be updated in main memory. With
Volatile keyword in Java this is handled by Java himself and such updates will be visible by all reader
threads.
=======Last point to get the same object afer De-Serialization============
Now suppose we want the above Singleton class to be serializable. We can implement the Serializable interface
for the above class and be done with it. But in that case we won’t be able to protect the singleton nature
of the instance, such that after de-serialization there will be more than one instance of the class.
This can be proved as follows:
Writing again the singleton pattern class:
////////////SingletonPattern.java
================================================
import java.io.ObjectStreamException;
import java.io.Serializable;
public class SingletonPattern implements Cloneable, Serializable{
private volatile static SingletonPattern object=null;
private SingletonPattern(){} //No subclass can be created because of this private default constructor.
public static SingletonPattern getInstance(){ //Never put synchronized in method, else other threads will be
//blocked for getting object.
if(object==null){ //Check instance, if there isn't one, enter a synchronized block.
synchronized (SingletonPattern.class) { //We only synchronized the first time through.
if(object==null){ //Once in the block, double check for null and create an instance.
object=new SingletonPattern();
}
}
}
return object;
}
public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException("Cloning of this class is not allowed");
}
}
================================================
//////Main class to fetch SingletonPattern Object and do Serialization:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class TestMain {
public static void main(String[] args) throws Exception{
SingletonPattern object=SingletonPattern.getInstance();
System.out.println("Original Singleton Object: "+object);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(new File("out3.dat")));
out.writeObject(object);
out.close();
ObjectInputStream in = new ObjectInputStream(new FileInputStream(new File("out3.dat")));
SingletonPattern deserObject = (SingletonPattern) in.readObject();
//After de-serialization we will get different object
System.out.println("Deserialized Singleton Object: "+deserObject);
in.close();
//Returning false, should return true.
System.out.println("This shows false, should be true: "+(object == deserObject));
//Returning true.
System.out.println("This shows true: "+(object == SingletonPattern.getInstance()));
}
}
////Output:
Original Singleton Object: SingletonPattern@164eee
Deserialized Singleton Object: SingletonPattern@16a04a
This shows false, should be true: false
This shows true: true
================================================
You can analyze the output, two different Singleton Objects are there and equality shows FALSE.
This breaks the rule of Singleton class. The way to avoid this is using another hook, the readResolve()
method. The readResolve() method is called when the ObjectInputStream has read an object from the
stream and is preparing to return it to the caller. ObjectInputStream checks whether the class of the
object defines the readResolve() method. If the method is defined, the readResolve method is called to
allow any changes in the object before it is returned.
So now we will add the readResolve() method in SingletonPattern.java, the modified code is:
================================
import java.io.ObjectStreamException;
import java.io.Serializable;
public class SingletonPattern implements Cloneable, Serializable{
private volatile static SingletonPattern object=null;
private SingletonPattern(){} //No subclass can be created because of this private default constructor.
public static SingletonPattern getInstance(){ //Never put synchronized in method, else other threads will be
//blocked for getting object.
if(object==null){ //Check instance, if there isn't one, enter a synchronized block.
synchronized (SingletonPattern.class) { //We only synchronized the first time through.
if(object==null){ //Once in the block, double check for null and create an instance.
object=new SingletonPattern();
}
}
}
return object;
}
public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException("Cloning of this class is not allowed");
}
private Object readResolve() throws ObjectStreamException {
return getInstance();
}
}
================================
Now if you run the TestMain program again you will see output (it will show equality as TRUE) and
objects are equal. It means that even after de-serialization, we still have only one instance of the class in
our JVM.
==============
//Output
Original Singleton Object: SingletonPattern@164efe
Deserialized Singleton Object: SingletonPattern@164efe
This shows false, should be true: true
This shows true: true
==============
--------------------------------END-----------------------------------
Friday, May 27, 2011
Transaction related Query to display two immediate transaction time difference
Transaction related Query to display two immediate transaction time difference
SELECT *
FROM
(
SELECT mt.transnumber
,LEAD(mt.transnumber, 1, 1) OVER (PARTITION BY TRNTYPE ORDER BY id) next_transnumber
,mt.trntype
,mt.modifiedtimestamp transaction_time
,LEAD(mt.modifiedtimestamp, 1, SYSDATE) OVER (PARTITION BY TRNTYPE ORDER BY id) next_transaction_time
,floor(((LEAD(mt.modifiedtimestamp, 1, SYSDATE) OVER (PARTITION BY TRNTYPE ORDER BY id) - mt.modifiedtimestamp)*24*60*60)/3600) time_diff
FROM mastertxn mt
WHERE trntype = 'TOPUP'
ORDER BY ID
)
WHERE time_diff >= 1
//Output pattern
TRANSNUMBER NEXT_TRANSNUMBER TRNTYPE TRANSACTION_TIME NEXT_TRANSACTION_TIME TIME_DIFF
1244 1360 TOPUP 05.10.2010 23:58:39 07.10.2010 10:48:43 34
1360 1408 TOPUP 07.10.2010 10:48:43 07.10.2010 16:34:55 5
1442 1507 TOPUP 07.10.2010 19:19:33 08.10.2010 11:26:43 16
Tuesday, May 17, 2011
How to fix "java.io.EOFException: Response contained no data"
How to fix "java.io.EOFException: Response contained no data"
Some time while working in Weblogic server environment, we are getting this exception intermittently:
java.io.EOFException: Response contained no data
at weblogic.net.http.MessageHeader.isHTTP(MessageHeader.java:222)
at weblogic.net.http.MessageHeader.parseHeader(MessageHeader.java:143)
at weblogic.net.http.HttpClient.parseHTTP(HttpClient.java:475)
at weblogic.net.http.HttpURLConnection.getInputStream(HttpURLConnection.java:368)
at weblogic.net.http.SOAPHttpURLConnection.getInputStream(SOAPHttpURLConnection.java:36)
The root cause of this is, You might be using a code base like this:
URLConnection con = url.openConnection();
con.setUseCaches(false);
con.setDoOutput(true);
con.setDoInput(true);
con.setRequestProperty("Content-Type", "text/xml");
//now construct the parameter data.
OutputStream os = con.getOutputStream();
os.write(formattedParams);
os.flush();
BufferedInputStream is = new BufferedInputStream(con.getInputStream());
ByteArrayOutputStream bos = new ByteArrayOutputStream();
buff = new byte[1024];
int bytesRead = -1;
while (-1 != (bytesRead = is.read(buff, 0, buff.length))) {
bos.write(buff, 0, buff.length);
}
retval = bos.toByteArray();
//Reason is: URLConnection is an Abstract class, so when your application runs on any server, Server specific URLConnection
API is getting used, here "weblogic.net.http.SOAPHttpURLConnection".
So "URLConnection.getInputStream()" is getting replaced with "weblogic.net.http.HttpURLConnection.getInputStream()".
And so some time it will go fine, other time it won't work. So this comes intermittently.
//Fix: Replace URLConnection API with Concrete class Apache's HttpClient API, so application will be server independent.
//Fix code base (You need “commons-httpclient-3.1.jar” for compiling this code snippet):
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.PostMethod;
PostMethod method=null;
HttpClient httpclient=null;
try {
String theURL = "URL"; //Constuct URL here.
httpclient = new HttpClient();
method = new PostMethod(theURL);
//If you want to add some header info
String encoding = new sun.misc.BASE64Encoder().encode("userPassword".getBytes());
method.setRequestHeader("Authorization","Basic " + encoding);
LogHelper.logMessage("Before sending SMS Message: "+message);
int respCode = httpclient.executeMethod(method);
if(respCode != HttpStatus.SC_OK) {
LogHelper.error("Http Method failed for URL :").append(theURL).toString()+", HTTPStatusCode:"+respCode);
}
else {
String responseString = method.getResponseBodyAsString(); //Give response as String.
/*
//Get response as Stream.
BufferedReader br = null;
FileWriter fw = null;
br = new BufferedReader(new InputStreamReader(httpPost.getResponseBodyAsStream()));
String tmp = null;
StringBuffer httpResponseBuffer = new StringBuffer();
int i = 0;
while ((tmp = br.readLine()) != null) {
if (i++ > 0) {
httpResponseBuffer.append(System.getProperty("line.separator"));
}
httpResponseBuffer.append(tmp);
}
if (writeToFile) {
fw=new FileWriter(pathToFile);
fw.write(httpResponseBuffer.toString());
fw.flush();
}
retval = httpResponseBuffer.toString();
*/
LogHelper.logMessage("Decoded Response String: "+responseString);
status = parseSMSResponse(responseString);
if (status != null) {
sendFlag = isStatusOK(status);
}
NOTE: Definitely it should work, tested code and we have used in our application.
---------------Definitely -----------------
Subscribe to:
Posts (Atom)