SWIG wrappers in Java and the C++ RAII pattern
There was recently some discussion on the QuantLib mailing list about problems arising in SWIG-generated Java wrappers for C++ classes (thread) on the mailing list, blog post. The immediate problem in these discussions was that the Java garbage collector runs in a thread which is separate to the main thread of execution of the native C++ code. Therefore, the C++ destructors are called at non-deterministic intervals and if they are not completely thread-safe the program will eventually fail.
There is however a more fundamental problem with all C++ classes using
sophisticated Resource Acquisition Is Initialisation
(RAII)
that are accessed from Java: the concept of destructors does not
exist in Java. Java does have the finalizer
concept but there is
no guarantee that a finalizer
will ever get called, or in what
order they will get called.
Of course, if the resource being acquired is simply memory then the Java garbage collector will reclaim this memory in an adequate way. But, often RAII is used in C++ for more sophisticated ways – in the case of the QuantLib example it was being used to establish an Observer/Observable relationship. In the C++ this relationship is broken in the destructor, and SWIG will call the C++ destructor from the Java finalizer. However, there is no guarantee in practice when the Java will call this finalizer, which means that one can have hundreds or even thousands of dangling Observers, or being continuously updated for no reason.
For this reason the use of finalizer
s in Java is very much
discouraged (see for example
this
article) and a more explicit control of non-memory resource allocation
and release is necessary. There is an excellent discussion of this
from C++ view point in the comments on this
post.
What are the implication when designing SWIG-ed libraries? It is best concentrate on the computation in the C/C++ layers and leave all resource allocation (except memory) and establishing of relationships between objects to the managed layer. The C++ RAII pattern simply does not map well to platforms like JVM…
For more information on QuantLib (see our dedicated pages)[https://bnikolic.co.uk/ql/].