diff --git a/build.xml b/build.xml
index 095da4bab5..70575132f8 100644
--- a/build.xml
+++ b/build.xml
@@ -526,11 +526,11 @@
+
+
-
-
-
+
diff --git a/native/Makefile b/native/Makefile
index 72dfe8a650..406abef669 100644
--- a/native/Makefile
+++ b/native/Makefile
@@ -60,6 +60,7 @@ endif
LIBRARY=$(BUILD)/$(LIBPFX)jnidispatch$(JNISFX)
TESTLIB=$(BUILD)/$(LIBPFX)testlib$(LIBSFX)
TESTLIB2=$(BUILD)/$(LIBPFX)testlib2$(LIBSFX)
+TESTLIBJAR=$(BUILD)/$(LIBPFX)testlibjar$(LIBSFX)
# Reasonable defaults based on GCC
LIBPFX=lib
@@ -296,7 +297,7 @@ else
$(CC) $(CFLAGS) -c $< $(COUT)
endif
-all: $(LIBRARY) $(TESTLIB) $(TESTLIB2)
+all: $(LIBRARY) $(TESTLIB) $(TESTLIB2) $(TESTLIBJAR)
install:
mkdir $(INSTALLDIR)
@@ -321,6 +322,9 @@ endif
$(TESTLIB2): $(BUILD)/testlib2.o
$(LD) $(LDFLAGS) $< $(TESTDEP)
+$(TESTLIBJAR): $(BUILD)/testlibjar.o
+ $(LD) $(LDFLAGS) $< $(LIBS)
+
ifneq ($(DYNAMIC_LIBFFI),true)
$(FFI_LIB):
@mkdir -p $(FFI_BUILD)
diff --git a/src/com/sun/jna/NativeLibrary.java b/src/com/sun/jna/NativeLibrary.java
index 8b4031222b..0fe07a6585 100644
--- a/src/com/sun/jna/NativeLibrary.java
+++ b/src/com/sun/jna/NativeLibrary.java
@@ -15,7 +15,10 @@
package com.sun.jna;
import java.io.File;
+import java.io.FileOutputStream;
import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.lang.ref.Reference;
import java.lang.reflect.Method;
@@ -165,6 +168,17 @@ else if (Platform.isWindows()) {
try { handle = Native.open(libraryPath); }
catch(UnsatisfiedLinkError e2) { e = e2; }
}
+ // As a last resort, try to extract the library from the JAR
+ if (handle == 0) {
+ final String embeddedLib = getEmbeddedLibraryPathFromJar(mapLibraryName(libraryName));
+ if (embeddedLib != null)
+ {
+ try {
+ handle = Native.open(embeddedLib);
+ }
+ catch (UnsatisfiedLinkError e2) { e = e2; }
+ }
+ }
if (handle == 0) {
throw new UnsatisfiedLinkError("Unable to load library '" + libraryName + "': "
+ e.getMessage());
@@ -172,6 +186,62 @@ else if (Platform.isWindows()) {
}
return new NativeLibrary(libraryName, libraryPath, handle, options);
}
+
+ private static String getEmbeddedLibraryPathFromJar(String libraryName)
+ {
+ // Do not extract the library from JAR if jna.nounpack=true
+ if (Boolean.getBoolean("jna.nounpack")) {
+ return null;
+ }
+ final String libraryPath = System.getProperty("os.name") + "-" + System.getProperty("os.arch") + "/";
+ File libFile;
+ try
+ {
+ libFile = extractEmbeddedLibraryResource(libraryPath, libraryName);
+ }
+ catch (IOException e)
+ {
+ return null;
+ }
+ if (libFile == null)
+ {
+ return null;
+ }
+ else
+ {
+ return libFile.getAbsolutePath();
+ }
+ }
+
+ private static File extractEmbeddedLibraryResource(String libraryPath, String libraryName) throws IOException {
+ final InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(libraryPath + libraryName);
+ if (is == null) {
+ return null;
+ }
+ FileOutputStream fos = null;
+ File lib = null;
+ try {
+ // Suffix is required on windows, or library fails to load
+ // Let Java pick the suffix, except on windows, to avoid
+ // problems with Web Start.
+ File dir = Native.getTempDir();
+ lib = File.createTempFile(libraryName, Platform.isWindows()?".dll":null, dir);
+ lib.deleteOnExit();
+ fos = new FileOutputStream(lib);
+ int count;
+ byte[] buf = new byte[1024];
+ while ((count = is.read(buf, 0, buf.length)) > 0) {
+ fos.write(buf, 0, count);
+ }
+ }
+ finally {
+ try { is.close(); } catch(IOException e) { }
+ if (fos != null) {
+ try { fos.close(); } catch(IOException e) { }
+ }
+ }
+ return lib;
+ }
private String getLibraryName(String libraryName) {
String simplified = libraryName;
diff --git a/test/com/sun/jna/NativeLibraryTest.java b/test/com/sun/jna/NativeLibraryTest.java
index 60e73eb833..189f0c0dbe 100644
--- a/test/com/sun/jna/NativeLibraryTest.java
+++ b/test/com/sun/jna/NativeLibraryTest.java
@@ -17,6 +17,7 @@
import java.util.Arrays;
import java.util.List;
+import junit.framework.Assert;
import junit.framework.TestCase;
public class NativeLibraryTest extends TestCase {
@@ -190,6 +191,18 @@ public void testGetProcess() {
// Access a common C library function
process.getFunction("printf");
}
+
+ public static interface TestLibraryInJar extends Library {
+ int test();
+ }
+
+ /**
+ * Tests that we can load a library which is embedded in the test JAR.
+ */
+ public void testEmbeddedLibrary() {
+ TestLibraryInJar lib = (TestLibraryInJar)Native.loadLibrary("testlibjar", TestLibraryInJar.class);
+ Assert.assertEquals(0, lib.test());
+ }
public static void main(String[] args) {
junit.textui.TestRunner.run(NativeLibraryTest.class);