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();