I am coding a download file controller
Sometime user will close the browser window before the file is fully written. - which is cool.
The problem is that my logs are full of this error:
org.apache.catalina.connector.ClientAbortException: java.io.IOException: An established connection was aborted by the software in your host machine
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:333)
at org.apache.catalina.connector.OutputBuffer.flushByteBuffer(OutputBuffer.java:758)
at org.apache.catalina.connector.OutputBuffer.append(OutputBuffer.java:663)
at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:368)
at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:346)
at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:96)
at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:2147)
at org.apache.commons.io.IOUtils.copy(IOUtils.java:2102)
at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:2123)
at org.apache.commons.io.IOUtils.copy(IOUtils.java:2078)
When I am trying to catch only this specific error eclipse is saying:
ClientAbortException cannot be resolved to a type
I have the project setup and running correctly so is it possible to catch only this specific exception:
org.apache.catalina.connector.ClientAbortException
I would like to keep the IOException in case of another catastrophe.
The ClientAbortException is derived from IOException. You have to inspect exactly what exception caused the IOException e:
...
} catch (FileNotFoundException fnfe) {
// ... handle FileNotFoundException
} catch (IOException e) {
String exceptionSimpleName = e.getCause().getClass().getSimpleName();
if ("ClientAbortException".equals(exceptionSimpleName)) {
// ... handle ClientAbortException
} else {
// ... handle general IOException or another cause
}
}
return null;
Instead of looking for a certain class name (that ties your application to a specific servlet container) I usually handle IOExceptions on write differently than IOExceptions on read, like so (very pseudo-ish code):
try {
byte[] buffer = ...
in.read(buffer);
try {
out.write(buffer);
} catch (IOException writeException) {
// client aborted request
}
} catch (IOException readException) {
// something went wrong -> signal 50x or something else
}
Worked out quite fine so far.
(As of #Nikolas Charalambidis answer)
Ignore "org.apache.catalina.connector.ClientAbortException:java.io.IOException: Connection reset by peer"
e.getCause().getClass().getSimpleName() == "IOException"
e.getMessage() == "java.io.IOException: Connection reset by peer"
And don't handle general IOException and another cause
...
} catch (IOException e) {
if (! e.getMessage().contains("Connection reset by peer")) {
throw e;
}
} finally {
close(output);
close(input);
}
...
Related
I know with Java 7 we can include multiple exceptions in the same catch block and separate them with pipe symbol. My question is for listing them in another file and catching all the exceptions listed in that file
You can do something like this:
Set<String> exceptionClasses = ... // load class names from file
try {
// ...
} catch (Exception e) {
if (exceptionClasses.contains(e.getClass().getName())) {
// handle exception
} else {
throw e; // propagate exception
}
}
I am new to android apps development. Recently,Im writing an application which able to show public ip based on Ipify. So far, i already:
Download the required jar file and put inside libs folder
I also compile file within gradle
Then i import required class it to my class
How to use Ipify, according to its website:
import org.ipify.Ipify;
public class HelloIP {
public static void main(String[] args) throws IOException {
System.out.println(Ipify.getPublicIp());
}
}
I write the following method to be invoked from another class:
public static String getPublicIp() throws IOException{
String ip = Ipify.getPublicIp();
return ip;
}
Another Class
//Get wifi
getWifiName wifiInfo = new getWifiName();
String myIP = wifiInfo.getPublicIp();
However, i keep getting:
Error:(52, 43) error: unreported exception IOException; must be caught
or declared to be thrown
I tried to modify the code and use the following try and catch, but still got the same error.
public static String getPublicIp() throws IOException{
String myip = Ipify.getPublicIp();
try{
return myip;
}
catch (IOException e){
System.out.println("General I/O exception: " + e.getMessage());
e.printStackTrace();
}
}
Im not too good in catch and throw exception, and already spent the whole day for this.I dont have idea anymore to fix this error..T.T
public static String getPublicIp() {
try{
return Ipify.getPublicIp();
}catch (IOException e){
System.out.println("General I/O exception: " + e.getMessage());
e.printStackTrace();
}
return null;
}
In case it didn't help, clean project in your IDE. You may have some data cached and it might be a reason.
Your problem is in another class! As you have declared the method getPublicIp() to throw IOException that class is afraid of receiving the Exception and therefor requests catching it.
In Java you have two types of Exceptions. Checked and unchecked. Checked Exceptions must be caught.
In Java Exceptions are used for marking unexpected situations. For example parsing non-numeric String to a number (NumberFormatException) or calling a method on a null reference (NullPointerException). You can catch them in many ways.
Unchecked Exceptions are those which extend RunTimeException. They are used for marking unexpected states usually caused by user's input. They shouldn't cause harm and should be worked out with business logic. You don't have to catch them, but sometimes you should.
On the other hand there are Checked Exceptions which mark dangerous situations. For example the application being unable to open a file. As those situations are found dangerous, you must catch them.
try{
//some code
} catch (NumberFormatException e1) {
e.printStackTrace() //very important - handles the Exception but prints the information!
} catch (NullPointerException e2) {
e.printStackTrace();
}
or using the fact, that they all extend Exception:
try {
//somecode
} catch (Exception e) {
e.printStackTrace;
};
or since Java 7:
try {
//somecode
} catch (NullPointerException | NumberFormatException e) {
e.printStackTrace;
};
I have some problems making the exception do that i want!. I have created a servlet, which i want to handle all exceptions. My class building for this scenario that i need help too you see under here:
Servlet:
This exception handling is only for 1 method,
try {
completed = func.addNewOperator(userId, name, ini, cpr, password, role);
}catch (Exception e) {
Error = "There was a problem with database access";
response.sendRedirect("SystemError.jsp?Error_resultat=" + Error);
} catch (IOException e) {
Error = "Error found with connection";
response.sendRedirect("SystemError.jsp?Error_resultat=" + Error);
} catch (RuntimeException e) {
Error = "Error found with entered values";
response.sendRedirect("SystemError.jsp?Error_resultat=" + Error);
} catch (Exception e) {
Error = "Serious error found!";
response.sendRedirect("SystemError.jsp?Error_resultat=" + Error);
The func.addNewOperator is called in my function class:
Function:
A small example from my function method you see under here:
public boolean addNewOperator(String userId, String name, String ini, String cpr, String password, String role ) throws Exception {
int id = Integer.parseInt(userId);
}
So lets say if it can't parse it to and integer, it should throws the exception to my servlet, but this is not working. I want to throw the exception to the servlet, and then the servlet should send a response to open SystemError.jsp with an error message as parameter.
Can anyone see if i forgot something??
The order is whatever matches first, get's executed (as the JLS clearly explains).
If the first catch matches the exception, it executes, if it doesn't, the next one is tried and on and on until one is matched or none are.
So, when catching exceptions you want to always catch the most specific first and then the most generic (as RuntimeException or Exception).
Read more Order of catching exceptions in Java
catch (Exception e) should be last catch block in the chain.
It's worth reading Oracle Java Tutorial - Exceptions
Try in this way and don't forget to log the exception in log file.
try {
completed = func.addNewOperator(userId, name, ini, cpr, password, role);
}catch (SQLException e) {
Error = "There was a problem with database access";
} catch (IOException e) {
Error = "Error found with connection";
} catch (RuntimeException e) {
Error = "Error found with entered values";
} catch (Exception e) {
Error = "Serious error found!";
}
if(Error != null){
response.sendRedirect("SystemError.jsp?Error_resultat=" + Error);
}
NumberFormatException is a RuntimeException.
First, you should never redirect to a jsp page, but forward to it. Normally, jsp files are placed under WEB-INF and are never called directly but allways through server. Here is one example of forwarding (derived from from Java Tips - How to forward requests from Servlet to JSP :) :
request.setAttribute("error", error);
getServletConfig().getServletContext().getRequestDispatcher("/WEB-INF/SystemError.jsp")
.forward(request,response);
and your get error (first letter lowercased because it's a variable) in your jsp via ${error}
And anyway, you shouldn't deal with that at your servlet level but delegates this low level job to the container as explained in that other post from SO : How to Properly Handle Exceptions in a JSP/Servlet App?.
Here is the code sample, I want to capture the exception throwed by mybatis:
String resource = "com/sureone/server/db/mybatis-config.xml";
Reader reader = null;
try {
reader = Resources.getResourceAsReader(resource);
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
sqlSession = factory.openSession(true);
tUserMapper = sqlSession.getMapper(TUserMapper.class);
if(tUserMapper.insert(user)>0){ <===Exception throwed here for duplicate entry problem
return verifyLogin(user.getAccount(),user.getPassword());
}
return null;
The exception I want to captured:
org.apache.ibatis.exceptions.PersistenceException:
### Error updating database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'userName' for key 'account_UNIQUE'
You can capture the PersistenceException as you would do usually :
try {
...
} catch (PersistenceException pe) {
}
But don't forget that this Exception wraps the real one:
From MyBatis code
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error committing transaction. Cause: " + e, e);
}
So if you would like the get a grip on the cause of the PersistenceException you'll have to use .getCause() method on the PersistenceException
Be aware that MyBatis can also launch its own PersistenceException (TooManyResultException,BindingException ...) classes, those won't have a cause Exception wrapped.
You can capture the ibatis exception by adding a try/catch block around your statements that invoke myBatis query/insert. For instance, if you use the SqlSessionTemplate and the selectList() method, you can do this:
try {
myResults = mySqlSessionTemplate.selectList("getInfoList", parameterMap);
} catch (final org.apache.ibatis.exceptions.PersistenceException ex) {
logger.error("Problem accessing database");
throw ex;
}
Whether you re-throw the exception or consume and deal with it here is your choice. However, beware of "eating" it and not dealing with the problem, since this will allow calling code to progress without knowing about the underlying data access problem.
While upgrading sun application server 8.2 to a new patch level an exception occurred and I don't know why. Following a code snippet from a Servlet:
public void init() throws ServletException {
Properties reqProperties = new Properties();
try {
reqProperties.load(this.getClass().getResourceAsStream(
"/someFile.properties"));
} catch (IOException e) {
e.printStackTrace();
}
...
}
The file does exists on the classpath and in previous patch versions it worked just fine. but now when deploying this result in a exception. The stack trace:
[#|2010-04-14T16:43:48.208+0200|WARNING|sun-appserver-ee8.2|javax.enterprise.system.core.classloading|_ThreadID=11;|loader.InputStreams with no valid reference is closed
java.lang.Throwable
at com.sun.enterprise.loader.EJBClassLoader$SentinelInputStream.<init>(EJBClassLoader.java:1172)
at com.sun.enterprise.loader.EJBClassLoader.getResourceAsStream(EJBClassLoader.java:858)
at java.lang.Class.getResourceAsStream(Class.java:1998)
at a.package.TestServlet.init(TestServlet.java:44)
at javax.servlet.GenericServlet.init(GenericServlet.java:261)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:592)
at org.apache.catalina.security.SecurityUtil$1.run(SecurityUtil.java:249)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAsPrivileged(Subject.java:517)
at org.apache.catalina.security.SecurityUtil.execute(SecurityUtil.java:282)
at org.apache.catalina.security.SecurityUtil.doAsPrivilege(SecurityUtil.java:165)
at org.apache.catalina.security.SecurityUtil.doAsPrivilege(SecurityUtil.java:118)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1093)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:931)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4183)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4535)
at com.sun.enterprise.web.WebModule.start(WebModule.java:241)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1086)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:847)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1086)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:483)
at org.apache.catalina.startup.Embedded.start(Embedded.java:894)
at com.sun.enterprise.web.WebContainer.start(WebContainer.java:741)
at com.sun.enterprise.web.HttpServiceWebContainer.startInstance(HttpServiceWebContainer.java:963)
at com.sun.enterprise.web.HttpServiceWebContainerLifecycle.onStartup(HttpServiceWebContainerLifecycle.java:50)
at com.sun.enterprise.server.ApplicationServer.onStartup(ApplicationServer.java:300)
at com.sun.enterprise.server.PEMain.run(PEMain.java:308)
at com.sun.enterprise.server.PEMain.main(PEMain.java:221)
|#]
I've no idea what could be the problem anyone have any idea?
(note that I changed some names in the code and stacktrace)
Are you sure it throws an exception? We get warnings like this in Glassfish all the time. The EJBClassLoader uses a throwable to dump the stack trace so it may look like an exception to you.
EJBClassLoader wraps all streams with sentinels. This warning simply tells you that your stream is not closed. You can safely ignore it. To get rid of the warning, you have to close the stream after you use it.
you should always close inputstreams after using:
public void init() throws ServletException {
InputStream str = null;
Properties reqProperties = new Properties();
try {
str = this.getClass().getResourceAsStream("/someFile.properties");
reqProperties.load(str);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (str != null) {
try {
str.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
btw, the finally clause can be made a lot simpler using apache commons / io:
finally {
IOUtils.closeQuietly(str);
}