diff --git a/build.xml b/build.xml
index 732beb568..2493553fc 100644
--- a/build.xml
+++ b/build.xml
@@ -64,6 +64,7 @@
+
@@ -270,21 +271,21 @@
-
+
-
-
+
+
-
-
+
+
@@ -601,14 +602,14 @@
-
+
@@ -648,9 +649,23 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -682,9 +697,9 @@
-
+
-
+
@@ -693,7 +708,7 @@
-
+
@@ -815,7 +830,7 @@
docletpathref="doclet.classpath"
classpathref="external.dependencies"
classpath="${java.classes}"
- maxmemory="2g"
+ maxmemory="2g"
additionalparam="${gatkdocs.include.hidden.arg} -private -build-timestamp "${build.timestamp}" -absolute-version ${build.version} -quiet">
@@ -974,10 +989,10 @@
-
-
-
-
+
+
+
+
@@ -990,7 +1005,7 @@
-
+
@@ -1149,31 +1164,31 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1220,7 +1235,7 @@
-
+
@@ -1266,13 +1281,13 @@
-
+
@@ -1308,7 +1323,7 @@
-
+
@@ -1442,7 +1457,7 @@
-
+
diff --git a/protected/java/src/org/broadinstitute/sting/utils/pairhmm/VectorLoglessPairHMM.java b/protected/java/src/org/broadinstitute/sting/utils/pairhmm/VectorLoglessPairHMM.java
index ef11600f0..aebe3cf95 100644
--- a/protected/java/src/org/broadinstitute/sting/utils/pairhmm/VectorLoglessPairHMM.java
+++ b/protected/java/src/org/broadinstitute/sting/utils/pairhmm/VectorLoglessPairHMM.java
@@ -59,6 +59,15 @@ import java.util.List;
import java.util.Map;
import java.util.HashMap;
+//For loading library from jar
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+
/**
* Created with IntelliJ IDEA.
@@ -111,7 +120,28 @@ public class VectorLoglessPairHMM extends JNILoglessPairHMM {
synchronized(isVectorLoglessPairHMMLibraryLoaded) {
//Load the library and initialize the FieldIDs
if(!isVectorLoglessPairHMMLibraryLoaded) {
- System.loadLibrary("VectorLoglessPairHMM");
+ try
+ {
+ //Try loading from Java's library path first
+ //Useful if someone builds his/her own library and wants to override the bundled
+ //implementation without modifying the Java code
+ System.loadLibrary("VectorLoglessPairHMM");
+ }
+ catch(UnsatisfiedLinkError ule)
+ {
+ //Could not load from Java's library path - try unpacking from jar
+ try
+ {
+ logger.info("libVectorLoglessPairHMM not found in JVM library path - trying to unpack from StingUtils.jar");
+ loadLibraryFromJar("/org/broadinstitute/sting/utils/pairhmm/libVectorLoglessPairHMM.so");
+ }
+ catch(IOException ioe)
+ {
+ //Throw the UnsatisfiedLinkError to make it clear to the user what failed
+ throw ule;
+ }
+ }
+
isVectorLoglessPairHMMLibraryLoaded = true;
jniInitializeClassFieldsAndMachineMask(JNIReadDataHolderClass.class, JNIHaplotypeDataHolderClass.class, enableAll); //need to do this only once
}
@@ -229,4 +259,75 @@ public class VectorLoglessPairHMM extends JNILoglessPairHMM {
super.close();
jniClose();
}
+
+ //Copied from http://frommyplayground.com/how-to-load-native-jni-library-from-jar
+ /**
+ * Loads library from current JAR archive
+ *
+ * The file from JAR is copied into system temporary directory and then loaded. The temporary file is deleted after exiting.
+ * Method uses String as filename because the pathname is "abstract", not system-dependent.
+ *
+ * @param filename The filename inside JAR as absolute path (beginning with '/'), e.g. /package/File.ext
+ * @throws IOException If temporary file creation or read/write operation fails
+ * @throws IllegalArgumentException If source file (param path) does not exist
+ * @throws IllegalArgumentException If the path is not absolute or if the filename is shorter than three characters (restriction of {@see File#createTempFile(java.lang.String, java.lang.String)}).
+ */
+ public static void loadLibraryFromJar(String path) throws IOException {
+
+ if (!path.startsWith("/")) {
+ throw new IllegalArgumentException("The path to be absolute (start with '/').");
+ }
+
+ // Obtain filename from path
+ String[] parts = path.split("/");
+ String filename = (parts.length > 1) ? parts[parts.length - 1] : null;
+
+ // Split filename to prexif and suffix (extension)
+ String prefix = "";
+ String suffix = null;
+ if (filename != null) {
+ parts = filename.split("\\.", 2);
+ prefix = parts[0];
+ suffix = (parts.length > 1) ? "."+parts[parts.length - 1] : null; // Thanks, davs! :-)
+ }
+
+ // Check if the filename is okay
+ if (filename == null || prefix.length() < 3) {
+ throw new IllegalArgumentException("The filename has to be at least 3 characters long.");
+ }
+
+ // Prepare temporary file
+ File temp = File.createTempFile(prefix, suffix);
+ //System.out.println("Temp lib file "+temp.getAbsolutePath());
+ temp.deleteOnExit();
+
+ if (!temp.exists()) {
+ throw new FileNotFoundException("File " + temp.getAbsolutePath() + " does not exist.");
+ }
+
+ // Prepare buffer for data copying
+ byte[] buffer = new byte[1024];
+ int readBytes;
+
+ // Open and check input stream
+ InputStream is = VectorLoglessPairHMM.class.getResourceAsStream(path);
+ if (is == null) {
+ 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);
+ }
+ } finally {
+ // If read/write fails, close streams safely before throwing an exception
+ os.close();
+ is.close();
+ }
+
+ // Finally, load the library
+ System.load(temp.getAbsolutePath());
+ }
}