Skip to content

Commit

Permalink
Ensure that temporary library files extracted from resource path are …
Browse files Browse the repository at this point in the history
…cleaned up, even in case something goes wrong while actually opening the library.

Added test for cleanup of extracted files on loading errors.

Documented cleanup of extracted files on loading errors in CHANGES.
  • Loading branch information
aschnab committed Jun 3, 2015
1 parent 6d0ff95 commit 6aacfe7
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 5 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ Features

Bug Fixes
---------
* [#450](https://github.com/twall/jna/pull/450): Libraries extracted to temp directory are now cleaned up in case of library loading errors, as well - [@aschnab](https://github.com/aschnab).
* [#319](https://github.com/twall/jna/pull/319): Fix direct-mapping type-mapped pointer result types - [@marco2357](https://github.com/marco2357).
* [#350](https://github.com/twall/jna/pull/350): Fix `jnacontrib.x11.api.X.Window.getXXXProperty`, returns `null` if the window property is not found - [@rm5248](https://github.com/rm5248).
* Fixed `com.sun.jna.platform.win32.Variant` and `TlbImp` - [@wolftobias](https://github.com/wolftobias).
Expand Down
13 changes: 8 additions & 5 deletions src/com/sun/jna/NativeLibrary.java
Original file line number Diff line number Diff line change
Expand Up @@ -257,11 +257,14 @@ else if (Platform.isWindows() && !isAbsolutePath) {
if (handle == 0) {
try {
File embedded = Native.extractFromResourcePath(libraryName, (ClassLoader)options.get(Library.OPTION_CLASSLOADER));
handle = Native.open(embedded.getAbsolutePath(), openFlags);
libraryPath = embedded.getAbsolutePath();
// Don't leave temporary files around
if (Native.isUnpacked(embedded)) {
Native.deleteLibrary(embedded);
try {
handle = Native.open(embedded.getAbsolutePath(), openFlags);
libraryPath = embedded.getAbsolutePath();
} finally {
// Don't leave temporary files around
if (Native.isUnpacked(embedded)) {
Native.deleteLibrary(embedded);
}
}
}
catch(IOException e2) { e = new UnsatisfiedLinkError(e2.getMessage()); }
Expand Down
33 changes: 33 additions & 0 deletions test/com/sun/jna/NativeLibraryTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,12 @@
*/
package com.sun.jna;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
Expand Down Expand Up @@ -284,6 +288,35 @@ public void testInterceptLastError() {
assertEquals("Wrong error", EXPECTED, get.invokeInt(null));
}

public void testCleanupOnLoadError() throws Exception {
Map options = new HashMap();
options.put(Library.OPTION_CLASSLOADER, new DisfunctClassLoader());
int previousTempFileCount = Native.getTempDir().listFiles().length;
try {
NativeLibrary.getInstance("disfunct", options);
fail("Expected NativeLibrary.getInstance() to fail with an UnsatisfiedLinkError here.");
} catch(UnsatisfiedLinkError e) {
int currentTempFileCount = Native.getTempDir().listFiles().length;
assertEquals("Extracted native library should be cleaned up again. Number of files in temp directory:", previousTempFileCount, currentTempFileCount);
}
}

// returns unloadable "shared library" on any input
private class DisfunctClassLoader extends ClassLoader {
public URL getResource(String name) {
try {
return new URL("jar", "", name);
} catch(MalformedURLException e) {
fail("Could not even create disfunct library URL: " + e.getMessage());
return null;
}
}

public InputStream getResourceAsStream(String name) {
return new ByteArrayInputStream(new byte[0]);
}
}

public static void main(String[] args) {
junit.textui.TestRunner.run(NativeLibraryTest.class);
}
Expand Down

0 comments on commit 6aacfe7

Please sign in to comment.