| // Test to check the exception classes in the throws attribute of the typemaps and except feature is working |
| |
| %module java_throws |
| |
| // throw is invalid in C++17 and later, only SWIG to use it |
| #define TESTCASE_THROW1(T1) throw(T1) |
| %{ |
| #define TESTCASE_THROW1(T1) |
| %} |
| |
| // Exceptions are chosen at random but are ones which have to have a try catch block to compile |
| %typemap(in, throws=" ClassNotFoundException") int num { |
| $1 = (int)$input; |
| } |
| %typemap(freearg, throws="InstantiationException ") int num "/*not written*/" |
| %typemap(argout, throws="CloneNotSupportedException ") int num "/*not written*/" |
| %typemap(check, throws="NoSuchFieldException") int num { |
| if ($input == 10) { |
| jenv->ExceptionClear(); |
| jclass excep = jenv->FindClass("java/lang/NoSuchFieldException"); |
| if (excep) |
| jenv->ThrowNew(excep, "Value of 10 not acceptable"); |
| return $null; |
| } |
| } |
| |
| // Duplicate exceptions should be removed from the generated throws clause |
| %typemap(out, throws="IllegalAccessException, NoSuchFieldException, CloneNotSupportedException ") short { |
| $result = (jshort)$1; |
| } |
| |
| %inline %{ |
| short full_of_exceptions(int num) { |
| return 0; |
| } |
| %} |
| |
| |
| %typemap(throws, throws="IllegalAccessException") int { |
| (void)$1; |
| jclass excep = jenv->FindClass("java/lang/IllegalAccessException"); |
| if (excep) { |
| jenv->ThrowNew(excep, "Test exception"); |
| } |
| return $null; |
| } |
| %inline %{ |
| bool throw_spec_function(int value) TESTCASE_THROW1(int) { throw (int)0; } |
| %} |
| |
| %catches(int) catches_function(int value); |
| %inline %{ |
| bool catches_function(int value) { throw (int)0; } |
| %} |
| |
| // Check newfree typemap throws attribute |
| %newobject makeTestClass; |
| %typemap(newfree, throws="NoSuchMethodException") TestClass* "/*not written*/" |
| %inline %{ |
| class TestClass { |
| int x; |
| public: |
| TestClass(int xx) : x(xx) {} |
| }; |
| TestClass* makeTestClass() { return new TestClass(1000); } |
| %} |
| |
| |
| // javain typemap throws attribute |
| // Will only compile if the fileFunction has a java.io.IOException throws clause as getCanonicalPath() throws this exception |
| %typemap(jstype) char* someFileArgument "java.io.File" |
| %typemap(javain, throws="java.io.IOException") char* someFileArgument "$javainput.getCanonicalPath()" |
| |
| %inline %{ |
| void fileFunction(char* someFileArgument) {} |
| %} |
| |
| |
| // javout typemap throws attribute |
| %typemap(javaout, throws="java.io.IOException") int { |
| int returnValue=$jnicall; |
| if (returnValue==0) throw new java.io.IOException("some IOException"); |
| return returnValue; |
| } |
| |
| %inline %{ |
| int ioTest() { return 0; } |
| %} |
| |
| // except feature (%javaexception) specifying a checked exception class for the throws clause |
| %typemap(javabase) MyException "Throwable"; |
| %typemap(javacode) MyException %{ |
| public static final long serialVersionUID = 0x52151000; // Suppress ecj warning |
| %} |
| %inline %{ |
| struct MyException { |
| MyException(const char *msg) {} |
| }; |
| %} |
| |
| %define JAVAEXCEPTION(METHOD) |
| %javaexception("MyException") METHOD %{ |
| try { |
| $action |
| } catch (MyException) { |
| jclass excep = jenv->FindClass("java_throws/MyException"); |
| if (excep) |
| jenv->ThrowNew(excep, "exception message"); |
| return $null; |
| } |
| %} |
| %enddef |
| |
| JAVAEXCEPTION(FeatureTest::FeatureTest) |
| JAVAEXCEPTION(FeatureTest::method) |
| JAVAEXCEPTION(FeatureTest::staticMethod) |
| |
| %inline %{ |
| struct FeatureTest { |
| static void staticMethod() { |
| throw MyException("no message"); |
| } |
| void method() { |
| throw MyException("no message"); |
| } |
| }; |
| %} |
| |
| %include <swiginterface.i> |
| %interface_impl(InterfaceTest); |
| JAVAEXCEPTION(imethod) |
| |
| %inline %{ |
| struct InterfaceTest { |
| virtual void imethod(bool raise) = 0; |
| virtual ~InterfaceTest() {} |
| }; |
| |
| struct InterfaceTestImpl : InterfaceTest { |
| void imethod(bool raise) { |
| if (raise) |
| throw MyException("raise message"); |
| } |
| }; |
| %} |
| |
| // Mixing except feature and typemaps when both generate a class for the throws clause |
| %typemap(in, throws="ClassNotFoundException") int both { |
| $1 = (int)$input; |
| } |
| %javaexception("MyException , NoSuchFieldException") globalFunction %{ |
| try { |
| $action |
| } catch (MyException) { |
| jclass excep = jenv->FindClass("java_throws/MyException"); |
| if (excep) |
| jenv->ThrowNew(excep, "exception message"); |
| return $null; |
| } |
| %} |
| |
| %inline %{ |
| void globalFunction(int both) { |
| throw MyException("no message"); |
| } |
| %} |
| |
| // 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/constructors) |
| %nojavaexception; |
| |