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 -----------------    

1 comment:

  1. Hi Deepak,

    We are getting same error "Response Contain No Data" while accessing the WSLD. We are working on HTTPS.
    It works fine on Lower version of Java (1.6_81) But it fails with that error on minor version upgraded Java (1.6_115). Weblogic we are using is - 10.3.6

    Please can you tell us - As per your post here it looks like there is some bug in weblogic which needs a patch or something ? or its just weblogic.net.http.SOAPHttpURLConnection issue.

    ReplyDelete