Native libraries (.dll/.so/.dylib) not removed from temp folder

Hi all,

We are running the XGBoost4J library inside our Java application which gets deployed at our customers to run locally. We are aware that the xgboost.dll/.so/.dylib from the JAR gets extracted to the temp folder so that the native code can be used by the Java wrapper.

However, we noticed that these temporary files do not get removed when the program exits (whether through an exception or by physically exiting the application by system.exit(0)). Because the temporary files have a randomly generated name, the next time when you start our application, a new .dll/.so/.dylib gets created. Over time, many of such files exist in the temp folder. Since our application is running on our customers’ machines, we don’t want to manually clean the temporary folder.

Other people/libraries seem to be struggling with similar issues, see e.g., https://coderanch.com/t/370563/java/deleteOnExit-work and https://stackoverflow.com/questions/31217720/jni-how-to-delete-temporary-dll-file-on-exit.

This issue can also be confirmed by running the unit tests inside jvm-packages. Every time when you run the tests, the .dll (on a windows machine) gets put inside the temp folder, but it doesn’t get removed.

This is a problem for us and I want to raise an issue on Github. Before I do that, I want to find out if there is already something in place that we can use to resolve this issue. For example, is it already possible to specify the location inside the temp folder where the .dll/.so/.dylib resources are stored?

In our mind, a possible quick fix could be to:

  • Allow a manual filename, that overrides the randomly generated filename of the resources. If the file already exists, overwrite it. That means that at most one of such files exist at any one time.
  • Allow to specify a folder within the temp folder where the dll/.so/.dylib resources are stored, so this specific folder can be cleaned up by our own application
  • Tell XGboost to use a specific folder to find the .dll/.so/.dylib libraries (e.g., using same path structure as in the jar)
  • We are open to other suggestions from the community as well

Thanks for your time,

Shady el Gewily

As far as I know XGBoost provides no such method. Please go ahead and file a new issue on GitHub.

Also, would you like to submit a pull request to add the functionality? I will be happy to review it.

Thanks for your response.

I will raise an issue and submit a pull request with my suggested implementation soon, and it would be great if you can review it.

As you mention, this is a known issue for this way of using JNI. It shouldn’t occur on non-Windows platforms, as there the OS doesn’t lock the library, however due to the way library unloading happens in Windows and how that interacts with the JVM it’s out of the library’s control.

It generates a random name to ensure that two JVMs running XGBoost don’t overwrite each other’s libraries, and I agree that this makes it tricky to deal with, but it’s hard to ensure that when testing multiple XGBoost variants they don’t collide.

If you extract the dll to a specific location and supply this system property then it will not extract the dll from the jar - https://github.com/dmlc/xgboost/blob/master/jvm-packages/xgboost4j/src/main/java/ml/dmlc/xgboost4j/java/NativeLibLoader.java#L117

Thanks Craigacp, very clear response. I was wondering whether it was something on our end, as I did see the references to deleteOnExit() in the code. But apparently this is how Windows deals with it.