If a Java method throws an exception, e.g. by using throw new
Exception("...")
and the exception is not caught by Java then it is
passed on as a Prolog exception. The thrown term is a
global reference to the Exception object. The following example
code illustrates how to handle Java exceptions in Prolog:
exception_example(JVM, ...) :- catch( %% Call Java method that may raise an exception jasper_call(JVM, ...), Excp, ( ( is_java_exception(JVM, Excp) -> print_exception_info(JVM, Excp) ; throw(Excp) % pass non-Java exceptions to caller ) ) ). is_java_exception(_JVM, Thing) :- var(Thing), !, fail. is_java_exception(_JVM, Thing) :- Thing = java_exception(_), % misc error in Java/Prolog glue !. is_java_exception(JVM, Thing) :- jasper_is_object(JVM, Thing), jasper_is_instance_of(JVM, Thing, 'java/lang/Throwable'). print_exception_info(_JVM, java_exception(Message)) :- !, format(user_error, '~NJasper exception: ~w~n', [Message]). print_exception_info(JVM, Excp) :- /* // Approximate Java code { String messageChars = excp.getMessage(); } */ jasper_call(JVM, method('java/lang/Throwable', 'getMessage', [instance]), get_message(+object('java/lang/Throwable'), [-chars]), get_message(Excp, MessageChars)), /* // Approximate Java code { StringWriter stringWriter = new StringWriter(); PrintWriter printWriter = new PrintWriter(stringWriter); excp.printStackTrace(printWriter); printWriter.close(); stackTraceChars = StringWriter.toString(); } */ jasper_new_object(JVM, 'java/io/StringWriter', init, init, StringWriter), jasper_new_object(JVM, 'java/io/PrintWriter', init(+object('java/io/Writer')), init(StringWriter), PrintWriter), jasper_call(JVM, method('java/lang/Throwable', 'printStackTrace', [instance]), print_stack_trace(+object('java/lang/Throwable'), +object('java/io/PrintWriter')), print_stack_trace(Excp, PrintWriter)), jasper_call(JVM, method('java/io/PrintWriter','close',[instance]), close(+object('java/io/PrintWriter')), close(PrintWriter)), jasper_call(JVM, method('java/io/StringWriter','toString',[instance]), to_string(+object('java/io/StringWriter'),[-chars]), to_string(StringWriter, StackTraceChars)), jasper_delete_local_ref(JVM, PrintWriter), jasper_delete_local_ref(JVM, StringWriter), %% ! exceptions are thrown as global references jasper_delete_global_ref(JVM, Excp), format(user_error, '~NJava Exception: ~s\nStackTrace: ~s~n', [MessageChars, StackTraceChars]).