1. Added support for building the PairHMM vector library into build.xml.
The library is compiled using makefile and copied into the directory: build/java/classes/org/broadinstitute/sting/utils/pairhmm/ 2. Bundled the library into StingUtils.jar. Unpacked and loaded at runtime without the need to set java.library.path Caveats: Platform independence has probably been thrown out of the window. Assumptions: a. make command exists at /usr/bin/make b. rsync command exists at /usr/bin/rsync c. icc is in the PATH of the user
This commit is contained in:
parent
7815c30df8
commit
dc44b64ad8
17
build.xml
17
build.xml
|
|
@ -64,6 +64,7 @@
|
|||
<property name="R.private.scripts.dir" value="${private.dir}/R/scripts" />
|
||||
<property name="R.protected.scripts.dir" value="${protected.dir}/R/scripts" />
|
||||
<property name="R.public.src.dir" value="${public.dir}/R/src" />
|
||||
<property name="vector.pairhmm.library.source.dir" value="${public.dir}/c++/VectorPairHMM" />
|
||||
|
||||
<!-- Build directories -->
|
||||
<property name="java.classes" value="${build.dir}/java/classes" />
|
||||
|
|
@ -648,9 +649,23 @@
|
|||
</copy>
|
||||
</target>
|
||||
|
||||
<target name="sting-utils.jar" depends="gatk.compile, init.jar, R.public.tar, R.script.stage">
|
||||
<target name="build.vector.pairhmm.library">
|
||||
<exec dir="${vector.pairhmm.library.source.dir}" executable="/usr/bin/make">
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="copy.vector.pairhmm.library" depends="build.vector.pairhmm.library">
|
||||
<exec executable="/usr/bin/rsync">
|
||||
<arg value="-a"/>
|
||||
<arg value="${vector.pairhmm.library.source.dir}/libVectorLoglessPairHMM.so"/>
|
||||
<arg value="${java.classes}/org/broadinstitute/sting/utils/pairhmm/libVectorLoglessPairHMM.so"/>
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="sting-utils.jar" depends="gatk.compile, init.jar, R.public.tar, R.script.stage, copy.vector.pairhmm.library">
|
||||
<jar jarfile="${dist.dir}/StingUtils.jar">
|
||||
<fileset dir="${java.classes}" includes="**/sting/utils/**/*.class"/>
|
||||
<fileset dir="${java.classes}" includes="**/sting/utils/**/*.so"/>
|
||||
<fileset dir="${java.classes}" includes="**/sting/commandline/**/*.class"/>
|
||||
<fileset dir="${java.classes}" includes="**/sting/pipeline/**/*.class"/>
|
||||
<fileset dir="${java.classes}" includes="**/sting/tools/**/*.class"/>
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue