diff --git a/CHANGES.current b/CHANGES.current
index 7a38f22b4..6dda7ff7a 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -1,6 +1,11 @@
Version 1.3.37 (in progress)
============================
+2008-12-23: wsfulton
+ [Java] Fix #2153773 - %nojavaexception was clearing the exception feature
+ instead of disabling it. Clearing checked Java exceptions also didn't work.
+ The new %clearjavaexception can be used for clearing the exception feature.
+
2008-12-22: wsfulton
Fix #2432801 - Make SwigValueWrapper exception safe for when copy constructors
throw exceptions.
diff --git a/Doc/Manual/Customization.html b/Doc/Manual/Customization.html
index e9d70e39a..ec73e5460 100644
--- a/Doc/Manual/Customization.html
+++ b/Doc/Manual/Customization.html
@@ -1019,6 +1019,20 @@ but this will:
+
+SWIG provides macros for disabling and clearing features. Many of these can be found in the swig.swg library file.
+The typical pattern is to define three macros; one to define the feature itself, one to disable the feature and one to clear the feature.
+The three macros below show this for the "except" feature:
+
+
+
+
+#define %exception %feature("except")
+#define %noexception %feature("except","0")
+#define %clearexception %feature("except","")
+
+
+
11.3.4 Features and default arguments
diff --git a/Doc/Manual/Java.html b/Doc/Manual/Java.html
index cbdcb5a9e..c5ff1f906 100644
--- a/Doc/Manual/Java.html
+++ b/Doc/Manual/Java.html
@@ -3820,7 +3820,9 @@ public:
In the example above, java.lang.Exception is a checked exception class and so ought to be declared in the throws clause of getitem.
Classes can be specified for adding to the throws clause using %javaexception(classes) instead of %exception,
where classes is a string containing one or more comma separated Java classes.
-The %nojavaexception feature is the equivalent to %noexception and clears previously declared exception handlers.
+The %clearjavaexception feature is the equivalent to %clearexception and clears previously declared exception handlers.
+The %nojavaexception feature is the equivalent to %noexception and disables the exception handler.
+See Clearing features for the difference on disabling and clearing features.
diff --git a/Examples/test-suite/java/java_throws_runme.java b/Examples/test-suite/java/java_throws_runme.java
index 3538aa6d4..6a73ea563 100644
--- a/Examples/test-suite/java/java_throws_runme.java
+++ b/Examples/test-suite/java/java_throws_runme.java
@@ -94,5 +94,20 @@ public class java_throws_runme {
if (!pass)
throw new RuntimeException("Test 7 failed");
+
+ // Test %nojavaexception
+ NoExceptTest net = new NoExceptTest();
+
+ pass = false;
+ try {
+ net.exceptionPlease();
+ pass = true;
+ }
+ catch (MyException e) {}
+
+ if (!pass)
+ throw new RuntimeException("Test 8 failed");
+
+ net.noExceptionPlease();
}
}
diff --git a/Examples/test-suite/java_throws.i b/Examples/test-suite/java_throws.i
index 3aa11defb..efa7da571 100644
--- a/Examples/test-suite/java_throws.i
+++ b/Examples/test-suite/java_throws.i
@@ -143,3 +143,41 @@ try {
}
%}
+// Test %nojavaexception
+%javaexception("MyException") %{
+/* global exception handler */
+try {
+ $action
+} catch (MyException) {
+ jclass excep = jenv->FindClass("java_throws/MyException");
+ if (excep)
+ jenv->ThrowNew(excep, "exception message");
+ return $null;
+}
+%}
+
+%nojavaexception *::noExceptionPlease();
+%nojavaexception NoExceptTest::NoExceptTest();
+
+// Need to handle the checked exception in NoExceptTest.delete()
+%typemap(javafinalize) SWIGTYPE %{
+ protected void finalize() {
+ try {
+ delete();
+ } catch (MyException e) {
+ throw new RuntimeException(e);
+ }
+ }
+%}
+
+%inline %{
+struct NoExceptTest {
+ unsigned int noExceptionPlease() { return 123; }
+ unsigned int exceptionPlease() { return 456; }
+ ~NoExceptTest() {}
+};
+%}
+
+// Turn global exceptions off (for the implicit destructors)
+%nojavaexception;
+
diff --git a/Lib/java/java.swg b/Lib/java/java.swg
index 7d1808632..f70d3f9cd 100644
--- a/Lib/java/java.swg
+++ b/Lib/java/java.swg
@@ -1191,7 +1191,8 @@ SWIG_PROXY_CONSTRUCTOR(true, true, SWIGTYPE)
#define %javaenum(wrapapproach) %feature("java:enum","wrapapproach")
#define %javamethodmodifiers %feature("java:methodmodifiers")
#define %javaexception(exceptionclasses) %feature("except",throws=exceptionclasses)
-#define %nojavaexception %feature("except","",throws="")
+#define %nojavaexception %feature("except","0",throws="")
+#define %clearjavaexception %feature("except","",throws="")
%pragma(java) jniclassclassmodifiers="class"
%pragma(java) moduleclassmodifiers="public class"
diff --git a/Source/Modules/java.cxx b/Source/Modules/java.cxx
index 37ce22377..742756f63 100644
--- a/Source/Modules/java.cxx
+++ b/Source/Modules/java.cxx
@@ -70,6 +70,7 @@ class JAVA:public Language {
String *imclass_cppcasts_code; //C++ casts up inheritance hierarchies intermediary class code
String *imclass_directors; // Intermediate class director code
String *destructor_call; //C++ destructor call if any
+ String *destructor_throws_clause; //C++ destructor throws clause if any
// Director method stuff:
List *dmethods_seq;
@@ -141,6 +142,7 @@ public:
imclass_cppcasts_code(NULL),
imclass_directors(NULL),
destructor_call(NULL),
+ destructor_throws_clause(NULL),
dmethods_seq(NULL),
dmethods_table(NULL),
n_dmethods(0),
@@ -1654,7 +1656,7 @@ public:
else
Replaceall(destruct, "$jnicall", "throw new UnsupportedOperationException(\"C++ destructor does not have public access\")");
if (*Char(destruct))
- Printv(proxy_class_def, "\n ", destruct_methodmodifiers, " void ", destruct_methodname, "() ", destruct, "\n", NIL);
+ Printv(proxy_class_def, "\n ", destruct_methodmodifiers, " void ", destruct_methodname, "()", destructor_throws_clause, " ", destruct, "\n", NIL);
}
/* Insert directordisconnect typemap, if this class has directors enabled */
@@ -1761,6 +1763,7 @@ public:
Clear(proxy_class_code);
destructor_call = NewString("");
+ destructor_throws_clause = NewString("");
proxy_class_constants_code = NewString("");
}
@@ -1819,6 +1822,8 @@ public:
proxy_class_name = NULL;
Delete(destructor_call);
destructor_call = NULL;
+ Delete(destructor_throws_clause);
+ destructor_throws_clause = NULL;
Delete(proxy_class_constants_code);
proxy_class_constants_code = NULL;
}
@@ -2336,6 +2341,7 @@ public:
if (proxy_flag) {
Printv(destructor_call, imclass_name, ".", Swig_name_destroy(symname), "(swigCPtr)", NIL);
+ generateThrowsClause(n, destructor_throws_clause);
}
return SWIG_OK;
}
@@ -2870,7 +2876,7 @@ public:
String *throws_attribute = NewStringf("%s:throws", attribute);
String *throws = Getattr(parameter, throws_attribute);
- if (throws) {
+ if (throws && Len(throws) > 0) {
String *throws_list = Getattr(n, "java:throwslist");
if (!throws_list) {
throws_list = NewList();