I'm very confused with handling errors on runnables passed to a threadpool.
I am doing everything by the book (literally, I'm adhering to Goetz' "Concurrency in Practice") and I'm not capturing any errors that Eclipse is showing me, and I'm getting weird NoClassDefFoundErrors even though my buildpath looks fine.
I tried killing my local repo and recloning it to get a fresh project build, but still getting the error. And none of my try-catches or System.out.println's are working either. Is there any way Eclipse can give me a better view of the error? Or a way to actually get the error handler's to work?
//ThreadPool and runnable that is failing, even with error captures
MyPriorityThreadPool.execute(new RunWithPriority(priority) {
Throwable thrown = null;
#Override
public void run() {
try {
batch.buildData();
} catch (Exception e) {
thrown = e;
}
finally {
if (thrown != null) {
thrown.printStackTrace();
}
}
}
});
}
I'm not quite sure what you're trying to accomplish, but the reason you're not catching the NoClassDefFoundError in your code is that you're catching Exception instead of Throwable or Error. Exception is more specific than Error and not what NoClassDefFoundError inherits from, so NoClassDefFoundError isn't caught by your catch expression.
Related
I'm trying to do java class loading. I'm using eclipse (luna) with 1.8.0_25 on a macos yosemite.
I'm using the following code in order to do it. It's working, until it reaches a class that has a dependency that isn't contained inside the jar that I'm loading classes from. Neither on the environment.
I'm not interested in this classes, so, it's safe to ignore then. So, I put it inside a try/catch and just log it.
But, when the exception occurs, the execution is canceled.
The exception (summarized) is:
Exception in thread "main" java.lang.NoClassDefFoundError: org/aspectj/runtime/internal/AroundClosure
Caused by: java.lang.ClassNotFoundException: org.aspectj.runtime.internal.AroundClosure
It rises at the exact line that is inside the inner try/catch block.
Why? Shouldn't the try/catch just log it and move on?
URLClassLoader ucl = null;
try {
URL url = Utils.getURIFromPath(jarFilePath).toURL();
URL[] urls = new URL[] { url };
ucl = new URLClassLoader(urls);
for (String tmp : classes) {
String clazz = tmp.substring(0, tmp.indexOf(".class")).replaceAll("/", ".");
try {
ucl.loadClass(clazz);
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
}
}
} catch (MalformedURLException e) {
LOGGER.error(e.getMessage(), e);
} finally {
if (ucl != null) {
try {
ucl.close();
} catch (IOException e) {
LOGGER.error(e.getMessage(), e);
}
}
}
NoClassDefFoundError is an Error, not an Exception, you should never1 try to catch an error, as stated here, catching it won't help you.
Check your classpath and fix it.
1 In some cases you might want to catch an error and handle it accordingly, as stated in the comments, maybe "never" is a little bit strong
Ok then try this:
catch (Throwable e) {
LOGGER.error(e.getMessage(), e);
}
Although using the above code will handle both Errors and Exceptions for you (both extend from Throwable), but it's not the right way to do it, only in very special cases do we handle errors using try-catch, errors are something we need to check in our code and resolve them.
It seems that one of the classes that you're using, probably one of the classes that you're trying to load with loadClass, has a dependency to classes from AspectJ, but the ClassLoader does not find the AspectJ classes. A possible solution is to make sure that AspectJ is on your classpath when you execute this.
It might also be that AspectJ already is on the classpath. If that's the case, it's just that your URLClassLoader doesn't know of your ClassPath. You might want to construct the URLClassLoader with a parent ClassLoader in place, like this:
ucl = new URLClassLoader(urls, getClass().getClassLoader());
The reason why the program doesn't just move on is that you're catching Exception. The hierarchy is class Throwable, class Exception extends Throwable and class Error extends Throwable, so catch (Exception e) will not catch Error. You might want to use catch(Exception | NoClassDefFoundError e) in this special case. Usually, catching Errors is not a good idea, but sometimes there are reasonable exceptions for errors like NoClassDefFoundError, OutOfMemoryError or StackOverflowError.
Ok, so im super, extra, brand new to java coding, but im slowly getting all the terms. But the real issue is this error. I'm trying to do a little coding snippet that, when started, will open a batch file (i'm much more experienced with them). I searched very much for answers, but nothing solved it, so i had o post about my specific situation.
This is said code:
public class Startbat {
public static void main(String[] args){
try {
Runtime.getRuntime().exec("cmd /c start hello.bat");
}
catch (IOException) {
System.out.println ("Something is wrong here...");
}
}
}
and when i try to javac it, i get this:
C:\Users\Owner>javac -g "C:\Users\Owner\Desktop\codes\codes\Startbat.java"
C:\Users\Owner\Desktop\codes\codes\Startbat.java:6: error: <identifier> expected
catch (IOException) {
^
1 error
I have found that the error I get is about the catch line/block not being in a method, when I have definitely made sure that it IS within the main.
I had a few error with the exception there, but i guess i solved it. i don't know what the exception would have been ((meaning how would that IOException occur from the runtime.exec stuff) meaning does that mean it won't start the batch file if it does get to work?).
Any help would be appreciated, even if its just "This is impossible to do"
You need to specify a variable for the exception, so you can use it later, for example...
catch (IOException exp) {
You should also consider printing the exception, at least to the console if not some kind of logger...
catch (IOException exp) {
ex.printStackTrace();
//...
This will make it easier to track down potential problems if/when they occur.
As a side note, you really should use ProcessBuilder instead of Runtime.exec, apart from anything else, it provides better management of the output streams and agruments that contain spaces...
I had a strange problem today... I'm going to make a simplified example since it "worth a thousands words" :D
public class Application() {
public static void main(String[] args) {
try {
A a = new A(); // this may throw exceptions
// (which will cause an ExceptionInInitializerError)
} catch (Throwable t) {
JOptionPane.showMessageDialog(null, "Oooops!");
System.exit(1);
}
}
}
Since it's a stand-alone application with a Swing GUI, my goal is to give a message to the user in case of any problems (in this case at startup)... the code above works in Eclipse IDE but when I export the project as executable jar by double-clicking on it, well, it just won't open.
So I try to execute it in cmd with java -jar application.jar and it prints in the shell that there was an ExceptionInInitializerError.
Why the error was not caught?
It doesn't work even if I specify catch (ExceptionInInitializerError e).
EDIT:
After more indepth debugging, I found out that this problem only happens when two particular exceptions occur and the latter occurs in the catch block of the former.
I corrected the bug by changing the order of some checks that I do on startup.
The problem btw should never happen since it was originated by a volountary mistake of the JDBC driver class name to load in a static block.
Well, at least it made me clearly understand why constructors and static initialization blocks should not throw exceptions: it makes debugging almost impossible in the case in which the class that throws the exception is used by many classes, since it may become very hard to find out when the class is loaded.
I can think of three possible explanations for an ExceptionInInitializerError not being caught in your example:
It could be being thrown by JOptionPane.showMessageDialog(null, "Oooops!");
It could be thrown before main is called.
It could be thrown on a different stack.
In fact, I think that the 2nd one is the most likely, as ExceptionInInitializerError is thrown when some unchecked exception is thrown (and not caught) during the initialization of a class. That could well be happening before you enter the try block.
I have some Scala code like this:
class Callee {
#throws(classOf[MyCheckedException])
def doStuff() {
}
}
Calling it from Java like so:
public class Caller {
public static void main(String[] args) {
// this won't compile; the Java compiler complains that the catch block is unreachable
// however without the catch block, it complains "unhandled exception MyCheckedException"
try {
new Callee().doStuff();
}
catch (MyCheckedException e) {
}
}
}
Removing the catch block results in an error from the Java compiler saying 'unhandled exception type MyCheckedException'. Adding the catch block for MyCheckedException results in the compiler complaining about the catch block being unreachable, because the exception is never thrown.
If I catch Exception and do an instanceOf, I can trap the correct exception coming out of doStuff, but I thought the #throws annotation was supposed to generate the right bytecode for the proper catch block to work. Am I wrong, or is there a bug here?
For the record, this is with Scala 2.9.2 and Java 1.6.
Edit: It compiles fine invoking javac/scalac using sbt from the command line. The error is only apparent during compile-as-you-type in Eclipse, which suggests the bug is in either the Eclipse Java Compiler or some part of the IDE. Can others reproduce it this way? I am using Eclipse 3.7.2
I can reproduce this on Helios with 2.9.1. It is a bug in the presentation compiler, and you should raise it as a bug on http://www.assembla.com/spaces/scala-ide/tickets.
For future reference, this issue has been fixed (https://github.com/scala-ide/scala-ide/commit/055a81cd3fe792e4327668791888c30cf04793f5). The fix is already available with both Scala IDE 2.0.x and Helium nightlies.
Furthermore, it will be included in the next Scala IDE 2.0.2 maintenace release.
(sorry for the additional noise, but I realized that having an answer was more visible than a simple comment)
public class StackTest {
public static void main(String[] args) {
show();
System.out.print("welcome back to maain");
display();
}
static void show(){
try{
show(); //recursion
}catch(StackOverflowError e){
System.out.print("error cought");
}
}
static void display(){
System.out.print("after stack overflow error");
}
}
In this program an StackOverflowError occurs but gets handled and the program does not terminated abnormally. why?
You can see this at http://ideone.com/vwSav
You can handle Errors because they are Throwable just like Exceptions.
Errors are designed to indicate problems outside your program's control, like OutOfMemoryError and StackOverflowError, but you can define your own errors, too.
Perhaps you are thinking that, or heard that, OutOFMemoryError can be caught but there's no guarantee you'll have enough space to execute the handler, so errors must in general not be something you can catch. In your case, though, you got away with it. No language rules were violated in the catching and handling of this error.
The real question is, should you catch them? Normally when an error, as opposed to an exception, is thrown, your application is very likely in an inconsistent state, making recovery a crapshoot at best. So be really, really careful. Better to forget it and let the app die though, since whatever is running after the handler is not guaranteed to be something you'd want to run.
Why would you expect it to terminate when you catch the exception (or rather the Error in this case)? What else would that catch block do?
You can catch and handle pretty much all error conditions, though usually you should only catch Exceptions.
You can catch any Throwable and it is up to the developer to handle it correctly. You can even handle ThreadDeath (triggered by a Thread.stop()) or another sub-class of Throwable (which is neither an Error or an Exception)
public class MyThrowable extends Throwable { } // checked "exception"
try {
throw new MyThrowable();
} catch (Throwable t) {
t.printStackTrace();
Thread.currentThread().stop(t); // rethrow blindly.
}
It will only be terminated abnormally if your exception is propagated all the way up to your main method and you don't handle it there. Usually happens for unchecked run time exceptions. If you want to terminate your program and shut down the VM you can call System.exit(int errorCode) in the catch block, there will be programmers which always complain here if that's done but that's a way to do it.
usually you don't catch Error, except for LinkageErrors, no class def found errors, unsatisfied link errors, incompatible class change errors..
also an outofmemory error (sometimes the stackoverflow exception) doesnot give control the catch block as there is no memory.