jnr / jffi

Java Foreign Function Interface
Apache License 2.0
168 stars 78 forks source link

JFFI leaves stale jffi*.dll files in temp folder #97

Closed david-bouyssie closed 3 years ago

david-bouyssie commented 3 years ago

This is a duplicate of https://github.com/jruby/jruby/issues/3657 But I put it here because I also observed this issue on windows with JFFI directly (without using JRuby). Do you know if there is a workaround?

Additional information: OS: Windows 10 jnr-ffi 2.2.1

headius commented 3 years ago

@david-bouyssie This is unfortunately still a known issue without a resolution (thanks for filing this so it is clear that jruby/jruby#3657 is a jffi issue).

As described in the JRuby issue, this is a limitation on Windows, preventing files from being deleted if they are still open in some process. We have looked at various ways to fix it internally but it is not an easy thing to solve.

The workarounds described in that issue are still valid and the best workaround for now: set up JVM properties to point at an already-unpacked version of the DLL, and we will not unpack another one.

I also describe there a possibility of using NIO.2 features to make the file deletable, but all opens of that file would have to use the same flags... including the open done by the JDK's own System.loadLibrary. Because of that, we still do not have a reliable solution to this problem (other than using JVM properties to point at a known location for the DLL.

headius commented 3 years ago

Ok so the workarounds are not perfect and we may need yet another.

However neither of these address your issue directly. It may be worth us adding a third property that is a full path from which we should load (and if it does not exist, to which we should extract) the native stub. That would allow you to be sure all executions use the same DLL.

david-bouyssie commented 3 years ago

Thank you that's helpful. What do you mean when you say "but it must match the naming in the native jar"? Do you have an example?

david-bouyssie commented 3 years ago

I tried different settings, and yes I confirm, having a full path would be the best solution. Actually this is what I'm also using for the library I want to load. In my case I specify it through a static method call (I defined a MyLibraryEnv static class that I use for configuration/extraction from resources).

headius commented 3 years ago

Back in the office today and I will be looking into this today. I think the best option at this point would be to provide a property you can set that will unpack the dll in a given location always and use the file that is there as long as it matches the one in the jar. That would not delete the file when finished, but it will not keep creating new ones.

Would that be sufficient for your case?

david-bouyssie commented 3 years ago

Yes would be perfect!

This is the solution I have currently implemented myself (by extracting my own copy of the libraries + setting jffi.boot.library.path ), but would be great if it was builtin.

headius commented 3 years ago

@david-bouyssie I have pushed a prototype of this behavior in #99, perhaps you could give it a try and see if it does what you need?

headius commented 3 years ago

This is not really fixed but it may not really be fixable. The improvements in #99 should help mitigate this problem for folks on Windows.

headius commented 3 years ago

jffi-1.3.2 has been released!

david-bouyssie commented 3 years ago

Awesome 😃

mohits commented 3 years ago

@headius - silly question here, but since jffi is part of the JRuby release, would this then be a part of the next release of JRuby?

david-bouyssie commented 3 years ago

Would be also great to release the artifact "jnr-ffi" based on jffi 1.3.2.