Reputation: 122008
I wrote a servlet to handle the exceptions occurring in my web app and mapped them in web.xml
<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/exceptionHandler</location>
</error-page>
Here is what I have done in the Exception Handling servlet service
method:
@Override
protected void service(HttpServletRequest req, HttpServletResponse arg1)
throws ServletException, IOException {
Object attribute = req.getAttribute("javax.servlet.error.exception");
if(attribute instanceof SocketException){
// don't do anything
}else{
super.service(req, arg1);
}
}.
Problem:
The above approach is not working and the stack trace is printing to the console. This occurs when the user requests something and then closes their browser.
Question:
How do I stop printing the stacktrace to the JBoss console whenever a SocketException
occurs?
Reason for doing this:
I want to avoid seeing all of the log's SocketException
s at the end of th day because I can't do anything with that information.
Upvotes: 20
Views: 18731
Reputation: 11
You can use the Logger
. For this you need log4j
library and all the desired behavior and exceptions are written to log file. For this you need to give the log file path
Upvotes: 1
Reputation: 1765
Another funky idea: you could create exception handler
class SocketExceptionSwallower implements Thread.UncaughtExceptionHandler {
public void uncaughtException(Thread t, Throwable e) {
if (e instanceof SocketException) {
// swallow
} else {
e.printStackTrace();
}
}
}
and registered with
Thread.setDefaultUncaughtExceptionHandler(new SocketExceptionSwallower());
or
Thread.currentThread().setUncaughtExceptionHandler(new SocketExceptionSwallower());
Simple, no overhead of another filter in chain, but it messes with threads and will probably break something in Java EE environment )
Might be useful in testing/experimenting or if you fully control threads in your own code
Upvotes: 1
Reputation: 46841
Use Jboss Custom Logging Handler to solve this problem.
If you don't want to log any SocketException
exception stack trace then just skip it while loggin into a file.
Steps to follow:
Here is the code:
package com.custom.jboss.logging;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Date;
import java.util.logging.ErrorManager;
import java.util.logging.Handler;
import java.util.logging.LogRecord;
public class SocketExceptionCustomLoggingHandler extends Handler {
private String logFile;
public BufferedWriter out = null;
public SocketExceptionCustomLoggingHandler() {
super();
logFile = "";
}
@Override
public void publish(LogRecord record) {
if (!initialize()) {
return;
}
if (isLoggable(record)) {
process(record);
}
}
private synchronized boolean initialize() {
if (out == null && logFile != null && !logFile.equals("")) {
FileWriter fstream = null;
try {
fstream = new FileWriter(logFile, true);
out = new BufferedWriter(fstream);
} catch (IOException e) {
reportError(e.getMessage(), e, ErrorManager.OPEN_FAILURE);
}
logToFile("Log file initialized. Logging to: " + logFile);
}
return true;
}
private void process(LogRecord logRecord) {
String log = getFormatter().format(logRecord);
if (log.indexOf("java.net.SocketException") == -1) {
logToFile(log);
}
}
private void logToFile(String text) {
try {
if (out != null) {
out.write((new Date()).toString() + "\t" + text + "\n");
out.flush();
}
} catch (IOException e) {
reportError(e.getMessage(), e, ErrorManager.WRITE_FAILURE);
}
}
@Override
public void flush() {
try {
if (out != null) {
out.flush();
}
} catch (IOException e) {
reportError(e.getMessage(), e, ErrorManager.FLUSH_FAILURE);
}
}
@Override
public void close() {
if (out != null) {
try {
out.close();
} catch (IOException e) {
reportError(e.getMessage(), e, ErrorManager.CLOSE_FAILURE);
}
}
}
public void setLogFile(String logFile) {
this.logFile = logFile;
}
}
The file is then packaged into a jar and placed in the modules directory.
i.e. Jboss-7.1.1/modules/com/custom/jboss/loggers/main
together with a module.xml file. The contents of the module.xml should look like this.
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.0" name="com.custom.jboss.loggers">
<resources>
<resource-root path="SocketExceptionHandler.jar"/>
<!-- Insert resources here -->
</resources>
<dependencies>
<module name="org.jboss.logging"/>
<module name="javax.api"/>
</dependencies>
</module>
Then modify the standalone.xml to support logging to the custom logger
<subsystem xmlns="urn:jboss:domain:logging:1.1">
...
<custom-handler name="SocketExceptionAppender" class="com.custom.jboss.logging.SocketExceptionCustomLoggingHandler" module="com.custom.jboss.loggers">
<level name="DEBUG"/>
<formatter>
<pattern-formatter pattern="%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"/>
</formatter>
<properties>
<property name="logFile" value="d:\\temp\\logfile.txt"/>
</properties>
</custom-handler>
...
<root-logger>
<level name="INFO"/>
<handlers>
<handler name="SocketExceptionAppender"/>
</handlers>
</root-logger>
</subsystem>
Add more handler in root-logger if needed such as FILE, CONSOLE etc.
SocketException
Please let me know if there is any issue.
Upvotes: 3
Reputation: 693
Instead of adding java.lang.Exception
in your web.xml why won't you just try to add socket exception in web.xml itself like below
<error-page>
<exception-type>java.net.SocketException</exception-type>
<location>/exceptionHandler</location>
</error-page>
and just do nothing in your servlet
Or instead add a empty jsp file like
<error-page>
<exception-type>java.net.SocketException</exception-type>
<location>/error.jsp</location>
</error-page>
Upvotes: 7
Reputation: 2608
As I understand it, exceptions are logged to the console when it is not caught before reaching the container. As such using a filter to catch unhandled exceptions makes sense.
Struts2 also has an exception 'interceptor' as its last interceptor, by default. See defaultStack. We need do override this interceptor if we need custom exception handling.
The only thing I would do additionally would be to log the exceptions (atleast to an errors-ignore.txt file) rather than completely skipping them.
Upvotes: 2
Reputation: 122008
Here is what I done so war as work around.
Added one filter and hijack all the request and response.Catch the exception and check the type.
/**
* Hijacks all the http request and response here.
* Catch the SocketException and do not print
* If other exceptions print to console
* date : 9-18-2013
*
* @author Suresh Atta
*
*/
public class ExceptionHandler implements Filter {
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1,
FilterChain arg2) throws IOException, ServletException {
try{
arg2.doFilter(arg0, arg1);
}catch(SocketException e ){
// Please don't print this to log.
}
}
}
And in web.xml
,filter mapping
<filter>
<filter-name>ExceptionHandler</filter-name>
<filter-class>com.nextenders.server.ExceptionHandler</filter-class>
</filter>
<filter-mapping>
<filter-name>ExceptionHandler</filter-name>
<dispatcher> REQUEST </dispatcher>
<url-pattern> /*</url-pattern>
</filter-mapping>
I'm not marking this as answer,since I'm not sure this is a standard way or not.Just a work around.
Upvotes: 7
Reputation: 923
You probably will have to override fillInStackTrade method
public static class CustomException extends Exception {
@Override
public Throwable fillInStackTrace() {
return null;
}
}
Upvotes: 2