I'm attempting to use SWIG to wrap a C++ class into a Java class. This C++ class has a method that throws an exception.
I have three goals, none of which are currently happening although I have followed the manual as I understand it:
throws <exceptiontype>
on the method that throws in C++java.lang.Exception
Exception.getMessage()
in the generated SWIG class.It seems that the root of the problem seems that my typemap
s are not being applied, as none of the above happens. What have I done wrong?
Minimal example is below. The C++ does not have to compile, I'm only interested in the generated Java. The class of the exception is irrelevant, and the code below uses IOException just because the documentation uses it. All code is adapted from examples here:
C++ header file (test.h):
#include <string>
class CustomException {
private:
std::string message;
public:
CustomException(const std::string& message) : message(msg) {}
~CustomException() {}
std::string what() {
return message;
}
};
class Test {
public:
Test() {}
~Test() {}
void something() throw(CustomException) {};
};
SWIG .i file:
%module TestModule
%{
#include "test.h"
%}
%include "std_string.i" // for std::string typemaps
%include "test.h"
// Allow C++ exceptions to be handled in Java
%typemap(throws, throws="java.io.IOException") CustomException {
jclass excep = jenv->FindClass("java/io/IOException");
if (excep)
jenv->ThrowNew(excep, $1.what());
return $null;
}
// Force the CustomException Java class to extend java.lang.Exception
%typemap(javabase) CustomException "java.lang.Exception";
// Override getMessage()
%typemap(javacode) CustomException %{
public String getMessage() {
return what();
}
%}
When running this with swig -c++ -verbose -java test.i
with SWIG 2.0.4, the exception class does not extend java.lang.Exception
and none of the Java methods have a throws
declaration.
You're going to kick yourself when you see this. A fixed version of your SWIG interface is:
%module TestModule
%{
#include "test.h"
%}
%include "std_string.i" // for std::string typemaps
// Allow C++ exceptions to be handled in Java
%typemap(throws, throws="java.io.IOException") CustomException {
jclass excep = jenv->FindClass("java/io/IOException");
if (excep)
jenv->ThrowNew(excep, $1.what());
return $null;
}
// Force the CustomException Java class to extend java.lang.Exception
%typemap(javabase) CustomException "java.lang.Exception";
// Override getMessage()
%typemap(javacode) CustomException %{
public String getMessage() {
return what();
}
%}
%include "test.h"
I.e. %include "test.h"
comes after the typemaps you wish to apply to the classes in test.h, not before. The typemaps need to have been seen by SWIG at the time the classes they apply to are first seen.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With