From d682651eb71d97c1839fdd778a34a3ed8b6c9b53 Mon Sep 17 00:00:00 2001
From: Herwig Hochleitner <hhochleitner@gmail.com>
Date: Thu, 13 Oct 2011 03:08:38 +0200
Subject: [PATCH 1/2] Added helpers for throwing and catching undeclared checked exceptions

---
 src/jvm/clojure/lang/Util.java |   56 ++++++++++++++++++++++++++++++++++++++++
 1 files changed, 56 insertions(+), 0 deletions(-)

diff --git a/src/jvm/clojure/lang/Util.java b/src/jvm/clojure/lang/Util.java
index 1fc0439..97422c6 100644
--- a/src/jvm/clojure/lang/Util.java
+++ b/src/jvm/clojure/lang/Util.java
@@ -169,4 +169,60 @@ static public RuntimeException runtimeException(Throwable e){
 	return new RuntimeException(e);
 }
 
+/**
+ * ************* Throwing and catching undeclared checked exceptions ********************
+ */
+
+@SuppressWarnings("unchecked") 
+// keeping the private name as a tribute
+// http://james-iry.blogspot.com/2010/08/on-removing-java-checked-exceptions-by.html
+static private <T extends Throwable, A> A pervertException(Throwable x) throws T {
+	throw (T) x;
+}
+
+static public <A> A throwUnchecked(Throwable t) {
+	return Util.<RuntimeException, A>pervertException(t);
+}
+
+static public <A> A throwCause(Throwable t) {
+	return throwUnchecked(t.getCause() != null ? t.getCause() : t);
+}
+
+// throws declarations, use when you want to catch undeclared checked exceptions
+
+static public <T extends Throwable> 
+	void declareThrows(Class<T> c) throws T {}
+
+static public <T1 extends Throwable, T2 extends Throwable> 
+	void declareThrows(Class<T1> c1, Class<T2> c2) throws T1, T2 {}
+
+static public <T1 extends Throwable, T2 extends Throwable, T3 extends Throwable> 
+	void declareThrows(Class<T1> c1, Class<T2> c2, Class<T3> c3) throws T1, T2, T3 {}
+
+static public <T1 extends Throwable, T2 extends Throwable, T3 extends Throwable, T4 extends Throwable> 
+	void declareThrows(Class<T1> c1, Class<T2> c2, Class<T3> c3, Class<T4> c4) throws T1, T2, T3, T4 {}
+
+// convenience for the common invoke
+
+static public <T extends Throwable> Object invokeThrowing(Class<T> c, IFn fn) throws T {
+	return fn.invoke();
+}
+
+static public <T extends Throwable> Object invokeThrowing(Class<T> c, IFn fn, Object arg) throws T {
+	return fn.invoke(arg);
+}
+
+static public <T extends Throwable> Object invokeThrowing(Class<T> c, IFn fn, Object arg1, Object arg2) throws T {
+	return fn.invoke(arg1, arg2);
+}
+
+static public <T extends Throwable> Object invokeThrowing(Class<T> c, IFn fn, Object arg1, Object arg2, 
+														  Object arg3) throws T {
+	return fn.invoke(arg1, arg2, arg3);
+}
+
+static public <T extends Throwable> Object invokeThrowing(Class<T> c, IFn fn, Object arg1, Object arg2, 
+														  Object arg3, Object arg4) throws T {
+	return fn.invoke(arg1, arg2, arg3, arg4);
+}
 }
-- 
1.7.3.4


From 0d4e563676a49b8e8d6f054a5a43ea8f23596240 Mon Sep 17 00:00:00 2001
From: Herwig Hochleitner <hhochleitner@gmail.com>
Date: Thu, 13 Oct 2011 04:08:55 +0200
Subject: [PATCH 2/2] Added Util.throwCause and used it to fix the unwanted wrapping of checked Exceptions in Reflector.java; fixes CLJ-855

---
 src/jvm/clojure/lang/Reflector.java |   26 +++++---------------------
 1 files changed, 5 insertions(+), 21 deletions(-)

diff --git a/src/jvm/clojure/lang/Reflector.java b/src/jvm/clojure/lang/Reflector.java
index a57c32b..bbb52cf 100644
--- a/src/jvm/clojure/lang/Reflector.java
+++ b/src/jvm/clojure/lang/Reflector.java
@@ -31,11 +31,7 @@ public static Object invokeInstanceMethod(Object target, String methodName, Obje
 		}
 	catch(Exception e)
 		{
-		if(e.getCause() instanceof Exception)
-			throw Util.runtimeException(e.getCause());
-		else if(e.getCause() instanceof Error)
-			throw (Error) e.getCause();
-		throw Util.runtimeException(e);
+                Util.throwCause(e);
 		}
 }
 
@@ -93,12 +89,8 @@ static Object invokeMatchingMethod(String methodName, List methods, Object targe
 		}
 	catch(Exception e)
 		{
-		if(e.getCause() instanceof Exception)
-			throw Util.runtimeException(e.getCause());
-		else if(e.getCause() instanceof Error)
-			throw (Error) e.getCause();
-		throw Util.runtimeException(e);
-		}
+                Util.throwCause(e);
+                }
 
 }
 
@@ -189,11 +181,7 @@ public static Object invokeConstructor(Class c, Object[] args) {
 		}
 	catch(Exception e)
 		{
-		if(e.getCause() instanceof Exception)
-			throw Util.runtimeException(e.getCause());
-		else if(e.getCause() instanceof Error)
-			throw (Error) e.getCause();
-		throw Util.runtimeException(e);
+                Util.throwCause(e);
 		}
 }
 
@@ -210,11 +198,7 @@ public static Object invokeStaticMethod(String className, String methodName, Obj
 		}
 	catch(Exception e)
 		{
-		if(e.getCause() instanceof Exception)
-			throw Util.runtimeException(e.getCause());
-		else if(e.getCause() instanceof Error)
-			throw (Error) e.getCause();
-		throw Util.runtimeException(e);
+                Util.throwCause(e);
 		}
 }
 
-- 
1.7.3.4

