Unlink temp file after loading on POSIX.

* Unlink the temporary library file after the last file descriptor to it is opened (`System.load(temp.getAbsolutePath())`) on systems that appear to be POSIX compliant.
This commit is contained in:
Isabell Cowan
2017-09-02 19:24:49 -05:00
parent c3fda8e996
commit ac61a4a32d

View File

@@ -24,7 +24,11 @@
package cz.adamh.utils;
import java.io.*;
import java.net.URI;
import java.nio.file.FileSystemNotFoundException;
import java.nio.file.FileSystems;
import java.nio.file.ProviderNotFoundException;
/**
* A simple library class which helps with loading dynamic libraries stored in the
* JAR archive. These libraries usualy contain implementation of some methods in
@@ -79,35 +83,59 @@ public class NativeUtils {
// Prepare temporary file
File temp = File.createTempFile(prefix, suffix);
temp.deleteOnExit();
if (!temp.exists()) {
throw new FileNotFoundException("File " + temp.getAbsolutePath() + " does not exist.");
}
boolean tempFileIsPosix = false;
try {
if (FileSystems.getDefault()
.supportedFileAttributeViews()
.contains("posix")) {
// Assume POSIX compliant file system, can be deleted after loading.
tempFileIsPosix = true;
}
} catch (FileSystemNotFoundException
| ProviderNotFoundException
| SecurityException e) {
// Assume non-POSIX, and don't delete until last file descriptor closed.
}
// Prepare buffer for data copying
byte[] buffer = new byte[1024];
int readBytes;
// Open and check input stream
InputStream is = NativeUtils.class.getResourceAsStream(path);
if (is == null) {
temp.delete();
throw new FileNotFoundException("File " + path + " was not found inside JAR.");
}
// Open output stream and copy data between source file in JAR and the temporary file
OutputStream os = new FileOutputStream(temp);
try {
while ((readBytes = is.read(buffer)) != -1) {
os.write(buffer, 0, readBytes);
}
} catch (Exception e) {
temp.delete();
throw e;
} finally {
// If read/write fails, close streams safely before throwing an exception
os.close();
is.close();
}
// Finally, load the library
System.load(temp.getAbsolutePath());
try {
// Load the library
System.load(temp.getAbsolutePath());
} finally {
if (tempFileIsPosix)
temp.delete();
else
temp.deleteOnExit();
}
}
}