Raising errors from Java stored procedures without "ORA-29532 Java call terminated by uncaught Java exception"
As I know, Oracle can't catch the Java errors directly. And the Oracle docs note of the ORA-29532 validate this idea:
ORA-29532: Java call terminated by uncaught Java exception: string
Cause: A Java exception or error was signaled and could not be resolved by the Java code.
Action: Modify Java code, if this behavior is not intended.
According to this text, I think you should handle the exception in the Java code.
You can solve that with these things:
- The return value of the Java function may be String - not void, and you may send the error description in the return variable.
- You may save the error to an Oracle table in the Java code and read it in the PL/SQL code.
- You just send the error to the Oracle user dump file with the
System.out.println();
.
Edit: Adam's final solution
This is roughly what I implemented based on the answer:
package mypackage;public class MyClass { public static final int SUCCESS = 1; public static final int FAILURE = 0; /** * This method actually performs the business logic. */ public static void doSomething(String arg1, String arg2) throws SQLException { // Actually do something... } /** * This method is called from PL/SQL. */ public static int doSomething(String arg1, String arg2, int[] errorCode, String[] errorMessage) { try { doSomething(arg1, arg2); return success(); } catch (SQLException e) { return failure(e, errorCode, errorMessage); } } private static int success() { return SUCCESS; } private static int failure(SQLException e, int[] errorCode, String[] errorMessage) { errorCode[0] = e.getErrorCode(); errorMessage[0] = e.getMessage(); return FAILURE; }}
Then in PL/SQL:
SUCCESS CONSTANT BINARY_INTEGER := 1;FAILURE CONSTANT BINARY_INTEGER := 0;SUBTYPE error_code_type IS BINARY_INTEGER;SUBTYPE error_message_type IS VARCHAR2(1000);PROCEDURE raise_error_if_failure ( status BINARY_INTEGER, error_code ERROR_CODE_TYPE, error_message ERROR_MESSAGE_TYPE ) ISBEGIN IF status = FAILURE THEN raise_application_error(error_code, error_message); END IF;END;FUNCTION do_something_in_java ( arg1 VARCHAR2, arg2 VARCHAR2, error_code OUT ERROR_CODE_TYPE, error_message OUT ERROR_MESSAGE_TYPE ) RETURN BINARY_INTEGER AS LANGUAGE JAVA NAME 'mypackage.MyClass.doSomething(java.lang.String, java.lang.String, int[], java.lang.String[]) return int';PROCEDURE do_something ( arg1 VARCHAR2, arg2 VARCHAR2 )IS error_code ERROR_CODE_TYPE; error_message ERROR_MESSAGE_TYPE;BEGIN raise_error_if_failure( do_something_in_java(arg1, arg2, error_code, error_message), error_code, error_message );END;
We have added DBMS_JAVA.endsession_and_related_state()
within oracle procedure to capture exception resolved the issue.Also Agree Adam solution above too.