I have a Fortran code which I try to wrap in a Java/Scala code. My issue is that the state of a variable in fortran is kept, even if I dispose the library between two calls:
Fortran-Code:
subroutine mySub()
implicit none
DOUBLE PRECISION x
COMMON/myCommon/ x
print*,x
x = 99.99
end subroutine mySub
And Java/Scala Code:
trait FortranLibrary extends Library {
// native symbols
def mysub_()
}
def main(args: Array[String]): Unit = {
var INSTANCE: FortranLibrary = Native.synchronizedLibrary(
Native.load("sub.so", classOf[FortranLibrary])
).asInstanceOf[FortranLibrary]
// call native subroutine
INSTANCE.mysub_()
println("------SECOND CALL-----")
// clean library, reload
INSTANCE = null
System.gc()
// make new instance
INSTANCE = Native.synchronizedLibrary(
Native.load(libpath, classOf[FortranLibrary])
).asInstanceOf[FortranLibrary]
// call native subroutine
INSTANCE.mysub_()
}
Prints to the console:
0.000000000000000E+000
------SECOND CALL-----
99.9899978637695
So the previously set x=99.99 is still present in the second call even though the library is disposed as proposed in How to dispose library loaded with JNA , how can avoid this?
EDIT: I'm using intel fortran compiler with -init:zero
, so variables should be re-initialized with 0
Under the hood, JNA keeps a reference to a NativeLibrary
object once you've loaded it, and does not release it unless dispose()
is explicitly called.
The dispose()
method is included in the object's finalize()
which would be called upon garbage collection, however, this cannot be relied upon to always execute. In the code snippet you've posted, you null the reference and use a single System.gc()
call, which is only a suggestion to release the object. A better option, which you've indicated in the comments that you've tried, is to call dispose()
or disposeAll()
yourself.
However, as also noted in my answer to your linked question, a small time delay is needed to ensure the native library doesn't return the same handle if it's immediately reloaded. JNA source code notes at least a 2ms delay works on OSX, and in your comments it seems you've been successful on your OS with a 10ms delay.