hc-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bugzi...@apache.org
Subject DO NOT REPLY [Bug 21754] New: - NullPointerException when releasing connection
Date Mon, 21 Jul 2003 02:22:07 GMT
DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG 
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://nagoya.apache.org/bugzilla/show_bug.cgi?id=21754>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND 
INSERTED IN THE BUG DATABASE.

http://nagoya.apache.org/bugzilla/show_bug.cgi?id=21754

NullPointerException when releasing connection

           Summary: NullPointerException when releasing connection
           Product: Commons
           Version: 2.0 Beta 2
          Platform: Other
        OS/Version: Other
            Status: NEW
          Severity: Major
          Priority: Other
         Component: HttpClient
        AssignedTo: commons-httpclient-dev@jakarta.apache.org
        ReportedBy: ch@ipin.com


Hi,

I'm using HTTP client 2.0 beta 2 in a multi-threaded environment with pooled
HTTP/1.1 connections. Since switching to 2.0 beta 2, I'm getting a
NullPointerException when releasing the connection. My code looks the following way:



public class StaticHttpConnector {

  protected final MultiThreadedHttpConnectionManager httpConnMgr =
        new MultiThreadedHttpConnectionManager();
  protected final HttpState state = new HttpState();
  protected final HostConfiguration hostConfig = new HostConfiguration();

  ...

  public StaticHttpConnector(URL url) {

    ....
    hostConfig.setHost(url.getHost(), url.getPort(), url.getProtocol());
    httpConnMgr.setMaxConnectionsPerHost(maxConnections);
  }

   /**
    * opens a connection with the remote system
    *
    * @return reference to connection if successfully established
    *
    * @throws ConnectorException if connection cannot be established after
    *         exhausting retry attempts
    *
    */
    private HttpConnection getConnection() throws ConnectorException {

        HttpConnection connection = null;
        Exception e = null;
        for (int i = 0; i < retryAttempts + 1; i++) {
            try {
                connection = httpConnMgr.getConnection(hostConfig, timeout);
                try {
                    connection.setSoTimeout(getSoTimeout());
                } catch (SocketException e1) {
                    throw new ConnectorException(e1);
                } catch (IllegalStateException e1) {
                    throw new ConnectorException(e1);
                }
                return connection;
            } catch (HttpException e1) {
                String emsg = UNABLE_TO_CONNECT + i;
                logger.warn(emsg, e1);
                e = e1;
                try {
                    Thread.sleep(retryInterval);
                } catch (InterruptedException e2) {
                    ; // ignore
                }
                continue;
            }
        }

        String emsg = UNABLE_TO_CONNECT + "FINAL";
        logger.error(emsg, e);
        throw new ConnectorException
            (ConnectorException.UNABLE_TO_CONNECT, emsg, e);
    }


    /**
     * communicate with remote system in request-reply fashion
     *
     * @param  request request to be sent
     *
     * @return response body
     *
     */
    public byte[] communicate(byte[] request) {

        ....

        // get connection
        HttpConnection connection = getConnection();

        // get POST method

        // Prepare HTTP post
        PostMethod method = new PostMethod();
        method.setRequestHeader(HttpConnectorUtil.HTTP_CONTENT_TYPE);
        method.setHttp11(true);

        // set path for POST method
        method.setPath(url.getPath());

        // set payload
        String payload = HttpConnectorUtil.toUTF8(bytes);
        method.setRequestBody(payload);

        // execute request
        int responseCode = -1;
        int retries = 0;
        try {
            while (responseCode == -1 && retries < 3) {
                try {

                    // execute POST request
                    responseCode = method.execute(state, connection);

                    // check response code
                    if (responseCode != HttpStatus.SC_OK) {
                        String emsg = "HTTP POST failed: " + responseCode +
                            " - " + url;
                        logger.warn(emsg);
                        throw new ConnectorException
                            (ConnectorException.HTTP_POST_FAILED, emsg);
                    }

                    // get response
                    byte[] resp = method.getResponseBody();

                    // get timestamp
                    long t1 = System.currentTimeMillis();

                    logger.info("Duration of communication with server: " +
                                url + " - " + (t1 - t0) + "ms");
                    return resp;

                } catch (HttpRecoverableException e) {
                    String emsg =
                        "(Recoverable) Error while sending data to server(" +
                        retries + "): " +
                        url + " - Reason: " + e.getLocalizedMessage();
                    logger.warn(emsg, e);
                    retries++;
                    continue;
                }
            }

            String emsg = "Unable to communicate with server: " + url +
                " - Reason: too many recoverable errors";
            logger.error(emsg);
            return null;

        } catch (HttpException e) {
            String emsg = "Error while sending data to server: " + url +
                " - Reason: " + e.getLocalizedMessage();
            logger.error(emsg, e);
            throw new ConnectorException
                (ConnectorException.HTTP_PROTOCOL_ERROR, emsg, e);
        } catch (IOException e) {
            String emsg = "Error while sending data to server: " + url +
                " - Reason: " + e.getLocalizedMessage();
            logger.error(emsg, e);
            throw new ConnectorException
                (ConnectorException.NESTED_IO_EXCEPTION, emsg, e);
        } catch (RuntimeException e) {
            String emsg = "Error while sending data to server: " + url +
                " - Reason: " + e.getLocalizedMessage();
            logger.error(emsg, e);
            throw new ConnectorException
                (ConnectorException.NESTED_RUNTIME_EXCEPTION, emsg, e);
        } finally {
            // release connection
            httpConnMgr.releaseConnection(connection);
        }

    }

    ...
}

This code has worked with a 2.0 alpha release, but in 2.0 beta 2 I'm getting a
NullPointerException when calling "httpConnMgr.releaseConnection(connection)".
Looking at it with a debugger, it seems that the 'wrappedConnection' becomes
null somewhere in process of executing the code.

I'm not sure why the 'wrappedConnection' reference becomes null in the process,
but I believe that I read somewhere (e.g. mailing lists) that this is normal if
the response was read. But this goes against my belief that I should release the
connection manually once the communication is done. 

Any explanation for this behaviour and what can I do to resolve this issue
without producing any memory leaks?

Mime
View raw message