diff --git a/src/main/org/apache/tools/ant/util/optional/JavaxScriptRunner.java b/src/main/org/apache/tools/ant/util/optional/JavaxScriptRunner.java
index ad5953460..d4171a73f 100644
--- a/src/main/org/apache/tools/ant/util/optional/JavaxScriptRunner.java
+++ b/src/main/org/apache/tools/ant/util/optional/JavaxScriptRunner.java
@@ -105,11 +105,16 @@ public class JavaxScriptRunner extends ScriptRunnerBase {
return engine.invoke("eval", String.class, getScript());
} catch (BuildException be) {
//catch and rethrow build exceptions
- throw be;
+
+ // this may be a BuildException wrapping a ScriptException
+ // deeply wrapping yet another BuildException - for
+ // example because of self.fail() - see
+ // https://issues.apache.org/bugzilla/show_bug.cgi?id=47509
+ throw unwrap(be);
} catch (Exception be) {
//any other exception? Get its cause
Throwable t = be;
- Throwable te = (Throwable) ReflectUtil.invoke(be, "getCause");
+ Throwable te = be.getCause();
if (te != null) {
if (te instanceof BuildException) {
throw (BuildException) te;
@@ -140,4 +145,21 @@ public class JavaxScriptRunner extends ScriptRunnerBase {
}
return ret;
}
+
+ /**
+ * Traverse a Throwable's cause(s) and return the BuildException
+ * most deeply nested into it - if any.
+ */
+ private static BuildException unwrap(Throwable t) {
+ BuildException deepest =
+ t instanceof BuildException ? (BuildException) t : null;
+ Throwable current = t;
+ while (current.getCause() != null) {
+ current = current.getCause();
+ if (current instanceof BuildException) {
+ deepest = (BuildException) current;
+ }
+ }
+ return deepest;
+ }
}
diff --git a/src/tests/antunit/taskdefs/optional/script/scriptdef-test.xml b/src/tests/antunit/taskdefs/optional/script/scriptdef-test.xml
index e8916815e..993b9577d 100644
--- a/src/tests/antunit/taskdefs/optional/script/scriptdef-test.xml
+++ b/src/tests/antunit/taskdefs/optional/script/scriptdef-test.xml
@@ -109,4 +109,17 @@
+
+
+
+
+
+
+
+
+