I am having following exception for application deployed at Jboss, Browser is IE8
2012-03-19 09:17:12,014 WARN [org.apache.catalina.core.ContainerBase.jboss.web]. [localhost]] Exception Processing ErrorPage[errorCode=404, location=/internalError.jsp]
ClientAbortException: java.net.SocketException: Broken pipe
at org.apache.catalina.connector.OutputBuffer.doFlush(OutputBuffer.java:327)
It seems that browser closed the socket before server writes internalError.jsp to it.
Please suggest how to solve it , or atleast how I can hide this exception.
Thanks
Hikumar
You cannot solve it. You cannot control whether the client will press Esc, or hastily click a different link, or close the browser, or have its machine crashed, etcetera, while your server is still handling the HTTP request/response.
You can "hide" it by a global filter (mapped on /*) which does something like this:
try {
chain.doFilter(request, response);
}
catch (ClientAbortException e) {
// Ignore.
}
This however brings a servletcontainer-specfic dependency in your code. The filter in question would result in NoClassDefFoundError on a servletcontainer of a different make which doesn't use Tomcat specific ClientAbortException. You might want to check the class simple name instead. Make use of the advantage that it's a subclass of IOException:
try {
chain.doFilter(request, response);
}
catch (IOException e) {
if (!e.getClass().getSimpleName().equals("ClientAbortException")) {
throw e;
}
}
Related
I have a class that wraps socketChannel and has a close() method as follows:
public void close() {
// ... logic ...
try {
socketChannel.close();
} catch (IOException e) {
// ???
}
this.isConnected = false;
}
I want in the end of this operation that socketChannel will be closed and not registered to its selector. I read and found that the above code is sufficient for that, but what happens if I got an IOException?
My feeling is that "swallowing" it is enough, but am i missing something?
The answer will depend on whether it matters that the close threw an exception. And if it matters, the next question is whether you need to do something about it ... other than reporting it.
Scenario #1.
A web server gets an exception when closing the output stream it sent the response on. A typical cause is that the user closed his web browser or lost his network connection at the wrong moment. The server-side exception doesn't matter (to the server / server admin) and is not even worth logging.
Scenario #2.
You are doing something that involves talking to multiple servers, and it is important to know that they all "got the message". If an exception occurs in the close, that may be an indication that that didn't happen. Probably you need to log this. Maybe you need to tell the servers. Maybe you need to cause some enclosing transaction to rollback.
I wonder how to handle exceptions correctly within a client server application. My client sends an information to the server(thread) which receives it within its run method.
I have already read something about uncaught exception handling when dealing with exceptions in the run method but want to know if this is the correct way to do it in my case.
I want to catch the exception on the client side.
I have in mind to do the following:
//Server
run(){
try{
...
}
catch(Exception e){
clientoutputstream.write(...); //transmitting the error
}
}
Any other suggestions?
You should put a try { } catch (IOException) around your read() call so you know if the other end has closed the connection. The other thing you might want to do is to put a try { } catch(Throwable) { } around the processing code so you can manually close the socket (Be very careful about catching Throwable) But if you just let the thread die the Socket will be closed when the object is garbage collected or when it times out
I sometimes get such stacktraces when downloading from HttpClient:
java.net.SocketTimeoutException: Read timed out, at java.net.SocketInputStream.socketRead0(Native Method),
...
at org.apache.commons.httpclient.ContentLengthInputStream.read(ContentLengthInputStream.java:170),
[wrapped]
org.apache.commons.httpclient.ProtocolException: The server example.com failed to respond with a valid HTTP response,
I've tried to recover from these errors by using a custom HttpMethodRetryHandler, but it seems I don't even enter the retryMethod(). It may be due to the fact the wrapped exception in SocketTimeoutException is a ProtocolException, which inherits from HttpException, and thus is not eligible to recovery, if I correctly understand the code of HttpMethodDirector class.
while (true) {
execCount++;
try {
...
} catch (HttpException e) {
// filter out protocol exceptions which cannot be recovered from
throw e;
} catch (IOException e) {
// test if this method should be retried
http://hc.apache.org/httpclient-3.x/exception-handling.html says
ProtocolException signals a violation of the HTTP specification. It is
important to note that HTTP proxies and HTTP servers can have
different level of HTTP specification compliance. It may be possible
to recover from some HTTP protocol exceptions by configuring
HttpClient to be more lenient about non-fatal protocol violations.
How can i achieve that? Is there an API allowing this or should I implement the mecanism to retry requests failing with HttpException?
There are a number of http.protocol.* configuration parameters that are defined here. You need to carefully look at each one of them and figure out what is the optimum leniency you need.
Do you see any possibility to log server side exceptions?Consider such code on the server side:
catch (Exception ex) {
throw new IllegalStateException (ex);
}
The exception is caused by the client-side call. Of course, exception will be noticed on the client-side. Is there any way to somehow handle it on the server side, without catch runtime exceptions? Some kind of handler that would allow me for example to log the stacktrace of the exception?
Any ideas?
you can wrap your server instance in a java.lang.reflect.Proxy and implement your server-side logging in the proxy. just make sure the proxy is exported, not the server implementation.
Commonly, the top level server method will have throws Exception.
If you wrap your "do it" code in this method with a try-catch Exception, and you can log it there as still throw it.
public Response myServerTopLevelMethod() throws Exception {
try {
myImplCode();
catch (Exception e) {
Log.error(e);
throw e;
}
}
Now you have some options about what to do. The basic options are:
You can just re-throw the Exception (as above)
You can play nice and return a "something bad happened" response - like many web servers do
Here's an example of option 2:
public Response myServerTopLevelMethod() throws Exception {
try {
myImplCode();
catch (Exception e) {
Log.error(e);
return new Response("Yikes! Something exploded... we'll look into it.");
}
}
Incidentally, the "Log + throw" of option 1 is one of the few times that you ever want to do this; at the top level method. At other times you should generally either log or throw, not both.
There are RMI system properties that will automatically log server-side exceptions for you. See the links on the RMI Home Page.
I've created a Java application that is split in different subcomponents, each of those runs on a separate Tomcat instance. Also, some components use a MySQL db through Hibernate.
I'm now creating an administration console where it's reported the status of all my Tomcat instances and of MySQL. I don't need detailed information, but knowing if they are running or not it's enough.
What could be the best solution to do that?
Thanks
Most straightforward way would be to just connect the server and see if it succeeds.
MySQL:
Connection connection = null;
try {
connection = DriverManager.getConnection(url, username, password);
// Succes!
} catch (SQLException e) {
// Fail!
} finally {
if (connection != null) try { connection.close(); } catch (SQLException ignore) {}
}
Tomcat:
try {
new URL(url).openConnection().connect();
// Succes!
} catch (IOException e) {
// Fail!
}
If you want a bit more specific status, e.g. checking if a certain DB table is available or a specific webapp resource is available, then you have to fire a more specific SELECT statement or HTTP request respectively.
I assume that you know the ports of which are running in advance (or from configuration files). The easiest way to check is to make socket connections to those ports like a telnet program does. Something like:
public boolean isServerUp(int port) {
boolean isUp = false;
try {
Socket socket = new Socket("127.0.0.1", port);
// Server is up
isUp = true;
socket.close();
}
catch (IOException e)
{
// Server is down
}
return isUp;
}
Usage:
isTomcatUp = isServerUp(8080);
isMysqlUp = isServerUp(3306);
However, I would say that is a false-negative check.. Sometimes it says server UP but the server is stuck or not responding...
I would make sure that what ever monitoring you setup is actually exercising some code. Monitoring the JVM via jmx can also be helpful after the fact. Check out http://www.cacti.net/ .
Firing a simple fixed query through MySQL
SELECT 'a-ok';
and have the .jsp return that a-ok text. If it times out and/or doesn't respond with a-ok, then something's hinky. If you need something more detailed, you can add extra checks, like requesting now() or something bigger, like SHOW INNODB STATUS.
The easiest thing is to look for the MySQL and Tomcat PID files. You need to look at your start scripts to make sure of the exact location, but once you find it, you simply test for existence of the pid file.
Create a servlet as a status page. In the servlet perform a cheap query, if the query succeeds let the servlet print OK otherwise Error. Put the servlet into a war and deploy it to all instances.
This could be used for checks in yor admin console by doing a loop over all instances.
I'd create a simple REST webservice that runs on each Tomcat instance and does a no-op query against the database. That makes it easy to drive from anywhere (command line, web app, GUI app, etc.)
If these are publicly available servers you can use a service like binarycanary.com to poll a page or service in your app.