views:

2085

answers:

5

I am using the getResponseBody() method of the org.apache.commons.httpclient.methods.PostMethod class. However, I am always getting a message written to the console at runtime:

WARNING: Going to buffer response body of large or unknown size. Using getResponseBodyAsStream instead is recommended.

In the code I have to write the response to a byte array anyway, so it is the getResponseBody() method that I ought to use. But is there an easy way that I can suppress the warning message so I don't have to look at it at every run?

If it was a compiler error, I'd use the @SuppressWarnings annotation, but this isn't a compile-time issue; it happens at runtime. Also, I could use getResponseBodyAsStream to write to a ByteArrayOutputStream, but this seems like a hacky way to get around the warning (extra lines of code to do what getResponseBody() is already doing for me).

My guess is that the answer involves System.out or System.err manipulation, but is there a good way to do this?

+1  A: 

Assuming the warning is written to stderr, you can always suppress the warning by piping stderr to /dev/null, or whatever the equivalent on your system is.

mipadi
+2  A: 

Is the library outputting through log4j? if so, editing the log4j.properties to set the output for this class to "ERROR" would work, e.g.

log4j.logger.org.apache.commons.httpclient.methods.PostMethod=ERROR
Steve B.
+8  A: 

If you want to cleanly stop this log entry, there's a tunable max that triggers the warning. I saw this looking at the code.

        int limit = getParams().getIntParameter(HttpMethodParams.BUFFER_WARN_TRIGGER_LIMIT, 1024*1024);
        if ((contentLength == -1) || (contentLength > limit)) {
            LOG.warn("Going to buffer response body of large or unknown size. "
                    +"Using getResponseBodyAsStream instead is recommended.");
        }

HttpMethodBase.setParams() looks like the place to set HttpMethodParams.BUFFER_WARN_TRIGGER_LIMIT to the desired value.

John M
We have a winnah!
Randolpho
Waiting to see if I get any more answers just in case, but yep, I think this is going to be the answer I accept. Some of the other responses have merit as well, though.
seansand
Interestingly, setting the parameter does not appear to have any effect. I am still seeing the warning regardless of what I set the parameter to be. It's hard to understand why this doesn't work:postMethod.getParams().setIntParameter( HttpMethodParams.BUFFER_WARN_TRIGGER_LIMIT, 1000000000);
seansand
Timing trouble? It sounds like a call to recycle() or setParams() after your getParams().setIntParameter() would clear out the parameters. Just guessing...
John M
+3  A: 

I would recommend that you do as the warning suggests and use a stream rather than a byte array. If the response you're trying to push is particularly large (suppose it's a large file), you will load it all into memory, and that'd be a very bad thing.

You're really better off using streams.

That said, you might hack around it by replacing System.err or System.out temporarily. They're just PrintStream objects, and they're settable with the setOut and setErr methods.

PrintStream oldErr = System.err;
PrintStream newErr = new PrintStream(new ByteArrayOutputStream());
System.setErr(newErr);

// do your work

System.setErr(oldErr);

Edit:

I agree that it would be preferable to use streams, but as it is now, the target API where I need to put the response is a byte array. If necessary, we can do a refactor to the API that will allow it to take a stream; that would be better. The warning is definitely there for a reason.

If you can modify the API, do so. Stream processing is the best way to go in this case. If you can't due to internal pressures or whatever, go @John M's route and pump up the BUFFER_WARN_TRIGGER_LIMIT -- but make sure you have a known contentLength, or even that route will fail.

Randolpho
I agree that it would be preferable to use streams, but as it is now, the target API where I need to put the response is a byte array. If necessary, we can do a refactor to the API that will allow it to take a stream; that would be better. The warning is definitely there for a reason.
seansand
As a stopgap, could you make use of ByteArrayOutputStream in some way? That might give you what you need, read from the response body stream, and then write it to the byte array that way?
Ian McLaird
+2  A: 

This issue has already been debated on the ASF JIRA. There are two ways to resolve this:

  • Set a higher value for BUFFER_WARN_TRIGGER_LIMIT. A high enough value is more likely to suppress the warning; however, that defeats the purpose of the warning itself. If you are buffering a lot of data to be eventually parsed in one pass, you are better off reading the data from a stream into an array before working on the array.
  • Set the logging level to a higher value for HttpClient, if you are comfortable with ERROR or FATAL.
Vineet Reynolds