简体   繁体   中英

Java: How do I catch an exception created inside the Method.invoke?

It seems like I can't catch exceptions in my code when the method was called from the Method.invoke method. How can catch it from inside the method itself?

void function() {
  try {
    // code that throws exception
  }
  catch( Exception e ) {
    // it never gets here!! It goes straight to the try catch near the invoke
  }
}

try {
  return method.invoke(callTarget, args);
}
catch( InvocationTargetException e ) {
  // exception thrown in code that throws exception get here!
}

Thanks!

You can get the real cause of the MethodInvocationException by checking its getCause() method that will return the exception thrown from function()

Note : you might need to call getCause() recursively on the returned exceptions to arrive at yours.

Note : getCause() returns a Throwable , which you will have to check for its actual type (eg instanceof or getClass() )

Note : getCause() returns null if no more "cause" is available -- you have arrived at the base cause of the execption thrown

Update :

The reason why the catch() in function() is not getting executed is that xxxError is not an Exception , so your catch won't catch it -- declare either catch(Throwable) or catch(Error) in function() if you don't want to declare all specific errors -- note that this is usually a bad idea (what are you going to dio with an OutOfMemoryError ?.

One reason that you can't catch UnsatisfiedLinkError with Exception is that UnsatisfiedLinkError is not a subclasses of Exception . In fact, it is a subclass of Error .

You should be careful about catching Error exceptions. They almost always indicate that something really bad has happened, and in most cases it is not possible to recover from them safely. For instance, an UnsatisfiedLinkError means that the JVM can't find a native library ... and that whatever depended on that library is (probably) unusable. Generally speaking. Error exceptions should be treated as fatal errors.

You throw exceptions as normal. The fact its inside an invoke makes no difference.

public class B {
    public static void function() {
        try {
            throw new Exception();
        } catch (Exception e) {
            System.err.println("Caught normally");
            e.printStackTrace();
        }
    }

    public static void main(String... args) throws NoSuchMethodException, IllegalAccessException {
        Method method = B.class.getMethod("function");
        Object callTarget = null;
        try {
            method.invoke(callTarget, args);
        } catch (InvocationTargetException e) {
            // should never get called.
            throw new AssertionError(e);
        }
    }
}

prints

Caught normally
java.lang.Exception
at B.function(B.java:15)
... deleted ...
at B.main(B.java:26)
... deleted ...

MethodInvocationException means you're calling the method wrong, it shouldn't have even gotten to inside your try block. From the docs:

Signals that the method with the specified signature could not be invoked with the provided arguments.

Edit: That's if this is the Spring MethodInvokationException, the Apache Velocity one does wrap function exceptions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM