diff --git a/ivy.xml b/ivy.xml
index 53c15d03c..6d580c3cc 100644
--- a/ivy.xml
+++ b/ivy.xml
@@ -10,5 +10,10 @@
+
+
+
+
+
diff --git a/java/src/org/broadinstitute/sting/gatk/CommandLineGATK.java b/java/src/org/broadinstitute/sting/gatk/CommandLineGATK.java
index d53638a19..e665e0f0d 100755
--- a/java/src/org/broadinstitute/sting/gatk/CommandLineGATK.java
+++ b/java/src/org/broadinstitute/sting/gatk/CommandLineGATK.java
@@ -42,9 +42,6 @@ public class CommandLineGATK extends CommandLineExecutable {
@Argument(fullName = "analysis_type", shortName = "T", doc = "Type of analysis to run")
private String analysisName = null;
- @Argument(fullName = "plugin_path", doc = "Which path will the GATK search for plugin walkers.", required = false)
- private String pluginPath = null;
-
// our argument collection, the collection of command line args we accept
@ArgumentCollection
private GATKArgumentCollection argCollection = new GATKArgumentCollection();
@@ -72,7 +69,7 @@ public class CommandLineGATK extends CommandLineExecutable {
@Override
protected GenomeAnalysisEngine getGATKEngine() {
if( GATKEngine == null )
- GATKEngine = new GenomeAnalysisEngine( pluginPath );
+ GATKEngine = new GenomeAnalysisEngine();
return GATKEngine;
}
diff --git a/java/src/org/broadinstitute/sting/gatk/GenomeAnalysisEngine.java b/java/src/org/broadinstitute/sting/gatk/GenomeAnalysisEngine.java
index ca378bb94..8836d99f4 100755
--- a/java/src/org/broadinstitute/sting/gatk/GenomeAnalysisEngine.java
+++ b/java/src/org/broadinstitute/sting/gatk/GenomeAnalysisEngine.java
@@ -70,10 +70,10 @@ public class GenomeAnalysisEngine {
* new MicroScheduler class we'll be able to delete that function.
*
*/
- public GenomeAnalysisEngine( String pluginPathName ) {
+ public GenomeAnalysisEngine() {
// make sure our instance variable points to this analysis engine
instance = this;
- walkerManager = new WalkerManager(pluginPathName);
+ walkerManager = new WalkerManager();
}
/**
diff --git a/java/src/org/broadinstitute/sting/gatk/WalkerManager.java b/java/src/org/broadinstitute/sting/gatk/WalkerManager.java
index 0e84f5884..5d211199b 100755
--- a/java/src/org/broadinstitute/sting/gatk/WalkerManager.java
+++ b/java/src/org/broadinstitute/sting/gatk/WalkerManager.java
@@ -1,19 +1,12 @@
package org.broadinstitute.sting.gatk;
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Arrays;
+import java.util.*;
import org.broadinstitute.sting.gatk.walkers.*;
import org.broadinstitute.sting.gatk.refdata.ReferenceOrderedDatum;
import org.broadinstitute.sting.gatk.refdata.ReferenceOrderedData;
-import org.broadinstitute.sting.utils.JVMUtils;
-import org.broadinstitute.sting.utils.PathUtils;
import org.broadinstitute.sting.utils.StingException;
+import org.broadinstitute.sting.utils.PackageUtils;
import org.apache.log4j.Logger;
import net.sf.picard.filter.SamRecordFilter;
@@ -33,42 +26,9 @@ public class WalkerManager {
private Map> walkersByName;
- public WalkerManager(String pluginDirectory) {
- try {
- List walkerCandidates = new ArrayList();
-
- // Load all classes that live in this jar.
- final File location = JVMUtils.getLocationFor( getClass() );
- walkerCandidates.addAll(loadClassesFromLocation(location));
-
- // Load all classes that live in the extension path.
- if (pluginDirectory == null)
- pluginDirectory = location.getParent() + File.separator + "walkers";
- logger.info("plugin directory: " + pluginDirectory);
-
- File extensionPath = new File(pluginDirectory);
- if (extensionPath.exists()) {
- List classFilesInPath = PathUtils.findFilesInPath(extensionPath, "", "class", false);
- walkerCandidates.addAll(JVMUtils.loadExternalClasses(extensionPath, classFilesInPath));
- List jarsInPath = PathUtils.findFilesInPath(extensionPath, "", "jar", false);
- for( String jarFileName: jarsInPath ) {
- File jarFile = new File( extensionPath, jarFileName );
- walkerCandidates.addAll(JVMUtils.loadExternalClassesFromJar(jarFile) );
- }
- }
-
- List> walkers = filterWalkers(walkerCandidates);
-
- if (walkerCandidates.isEmpty())
- throw new RuntimeException("No walkers were found.");
-
- walkersByName = createWalkerDatabase(walkers);
- }
- // IOExceptions here are suspect; they indicate that the WalkerManager can't open its containing jar.
- // Wrap in a RuntimeException.
- catch (IOException ex) {
- throw new RuntimeException(ex);
- }
+ public WalkerManager() {
+ List> walkers = PackageUtils.getClassesImplementingInterface(Walker.class);
+ walkersByName = createWalkerDatabase(walkers);
}
/**
@@ -206,38 +166,6 @@ public class WalkerManager {
return filters;
}
- /**
- * Load classes internal to the classpath from an arbitrary location.
- *
- * @param location Location from which to load classes.
- * @return List of classes.
- * @throws IOException Problem occurred reading classes.
- */
- private List loadClassesFromLocation(File location)
- throws IOException {
- if (location.getAbsolutePath().endsWith(".jar"))
- return JVMUtils.loadInternalClassesFromJar(location);
- else {
- List classFileNames = PathUtils.findFilesInPath(location, "", "class", true);
- return JVMUtils.loadInternalClasses(classFileNames);
- }
- }
-
- /**
- * Given a list of classes, return a list of those classes which extend from the Walker base interface.
- *
- * @param classes Arbitrary list of classes.
- * @return List of classes extending from Walker.
- */
- private List> filterWalkers(List classes) {
- List> walkerClasses = new ArrayList>();
- for( Class clazz: classes ) {
- if( JVMUtils.isConcreteImplementationOf(clazz,Walker.class) )
- walkerClasses.add( (Class extends Walker>)clazz );
- }
- return walkerClasses;
- }
-
/**
* Instantiate the list of walker classes. Add them to the walker hashmap.
*
diff --git a/java/src/org/broadinstitute/sting/playground/gatk/walkers/variants/VariantFiltrationWalker.java b/java/src/org/broadinstitute/sting/playground/gatk/walkers/variants/VariantFiltrationWalker.java
index 08fff4ba4..7d719ca37 100755
--- a/java/src/org/broadinstitute/sting/playground/gatk/walkers/variants/VariantFiltrationWalker.java
+++ b/java/src/org/broadinstitute/sting/playground/gatk/walkers/variants/VariantFiltrationWalker.java
@@ -16,9 +16,7 @@ import org.broadinstitute.sting.playground.gatk.walkers.variants.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
+import java.util.*;
/**
* VariantFiltrationWalker applies specified conditionally independent features to pre-called variants, thus modifying
@@ -33,8 +31,8 @@ public class VariantFiltrationWalker extends LocusWalker {
@Argument(fullName="list", shortName="ls", doc="List the available features and exclusion criteria and exit") public Boolean LIST = false;
@Argument(fullName="truth", shortName="truth", doc="Operate on truth set only") public Boolean TRUTH = false;
- private ArrayList featureClasses;
- private ArrayList exclusionClasses;
+ private List> featureClasses;
+ private List> exclusionClasses;
private PrintWriter vwriter;
private HashMap ewriters;
@@ -143,7 +141,7 @@ public class VariantFiltrationWalker extends LocusWalker {
* @param classes an ArrayList of classes
* @return String of available classes
*/
- private String getAvailableClasses(ArrayList classes) {
+ private String getAvailableClasses(List> classes) {
String availableString = "";
for (int classIndex = 0; classIndex < classes.size(); classIndex++) {
diff --git a/java/src/org/broadinstitute/sting/playground/somaticcoverage/SomaticCoverageTool.java b/java/src/org/broadinstitute/sting/playground/somaticcoverage/SomaticCoverageTool.java
index 2853ce766..e1e1abce6 100644
--- a/java/src/org/broadinstitute/sting/playground/somaticcoverage/SomaticCoverageTool.java
+++ b/java/src/org/broadinstitute/sting/playground/somaticcoverage/SomaticCoverageTool.java
@@ -63,7 +63,7 @@ public class SomaticCoverageTool extends CommandLineExecutable {
@Override
protected GenomeAnalysisEngine getGATKEngine() {
if( GATKEngine == null )
- GATKEngine = new GenomeAnalysisEngine( null );
+ GATKEngine = new GenomeAnalysisEngine();
return GATKEngine;
}
diff --git a/java/src/org/broadinstitute/sting/utils/JVMUtils.java b/java/src/org/broadinstitute/sting/utils/JVMUtils.java
index 142deddaf..c4d63b08e 100755
--- a/java/src/org/broadinstitute/sting/utils/JVMUtils.java
+++ b/java/src/org/broadinstitute/sting/utils/JVMUtils.java
@@ -1,14 +1,5 @@
package org.broadinstitute.sting.utils;
-import java.io.File;
-import java.io.IOException;
-import java.io.FileInputStream;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.jar.JarInputStream;
-import java.util.jar.JarEntry;
-import java.net.URL;
-import java.net.URLClassLoader;
import java.lang.reflect.Modifier;
/**
@@ -26,189 +17,14 @@ public class JVMUtils {
*/
private JVMUtils() { }
- /**
- * Determines which location contains the specified class.
- *
- * @return Location (either jar file or directory) of path containing class.
- */
- public static File getLocationFor( Class clazz ) throws IOException {
- try {
- java.net.URI locationURI = clazz.getProtectionDomain().getCodeSource().getLocation().toURI();
- return new File(locationURI);
- }
- catch (java.net.URISyntaxException ex) {
- // a URISyntaxException here must be an IO error; wrap as such.
- throw new IOException(ex);
- }
- catch ( NullPointerException ne ) {
- throw new IOException("Can not extract code source location for "+clazz.getName());
- }
- }
-
- /**
- * Loads concrete classes from a jar which are both in the same package or 'sub-package' of baseClass,
- * and which extend from baseClass. Loaded classes must already be on the classpath.
- *
- * @param jarFile The jar file to search.
- * @return A list of classes derived from baseClass.
- */
- public static List loadInternalClassesFromJar(final File jarFile)
- throws IOException {
- return loadClassesFromJar( jarFile, new InternalLoadingStrategy() );
- }
-
- /**
- * Loads concrete classes from a jar which are both in the same package or 'sub-package' of baseClass,
- * and which extend from baseClass. Loaded classes can be outside of the current classpath.
- *
- * @param jarFile The jar file to search.
- * @return A list of classes derived from baseClass.
- */
- public static List loadExternalClassesFromJar(final File jarFile)
- throws IOException {
- return loadClassesFromJar( jarFile, new ExternalLoadingStrategy(jarFile) );
- }
-
- /**
- * Loads a list of classes currently on the classpath.
- *
- * @param classFileNames List of files representing classes.
- * @return class objects.
- * @throws IOException Unable to open any of the found classes.
- */
- public static List loadInternalClasses(List classFileNames)
- throws IOException {
- return loadClasses( classFileNames, new InternalLoadingStrategy() );
- }
-
- /**
- * Load loose classes, external to the classloader, from the specified directory.
- *
- * @param path source path from which to load classes.
- * @return A list of all loose classes contained in the path directory.
- */
- public static List loadExternalClasses(final File path, List classFileNames)
- throws IOException {
- return loadClasses( classFileNames, new ExternalLoadingStrategy( path ) );
- }
-
- /**
- * Convert a filename of the form a/b/c.class to a.b.c. Makes no assurances about whether the
- * class is valid on any classloader.
- *
- * @param fileName Filename to convert.
- * @return classname represented by that file.
- */
- public static String fileNameToClassName(String fileName) {
- return fileName.substring(0, fileName.lastIndexOf(".class")).replace('/', '.');
- }
-
/**
* Is the specified class a concrete implementation of baseClass?
* @param clazz Class to check.
- * @param baseClass Base class to check against.
- * @return True if clazz implements baseClass and is not abstract / an interface. False otherwise.
+ * @return True if clazz is concrete. False otherwise.
*/
- public static boolean isConcreteImplementationOf( Class clazz, Class baseClass ) {
- return baseClass.isAssignableFrom(clazz) &&
- !Modifier.isAbstract(clazz.getModifiers()) &&
- !Modifier.isInterface(clazz.getModifiers());
- }
-
- /**
- * Loads a list of classes from the given jar, using the provided loading strategy.
- * @param jarFile Jar file from which to load.
- * @param loader Dictates how these classes should be loaded.
- * @return A list of loaded classes.
- * @throws IOException In case there's an IO error trying to load the jar.
- */
- private static List loadClassesFromJar( final File jarFile, final LoadingStrategy loader )
- throws IOException {
- List classes = new ArrayList();
-
- JarInputStream jarInputStream = new JarInputStream(new FileInputStream(jarFile));
-
- try {
- JarEntry jarEntry = jarInputStream.getNextJarEntry();
-
- while (jarEntry != null) {
- String jarEntryName = jarEntry.getName();
- if (jarEntryName.endsWith(".class")) {
- String className = fileNameToClassName(jarEntryName);
- classes.add( loader.load( className ) );
- }
- jarEntry = jarInputStream.getNextJarEntry();
- }
- }
- catch (ClassNotFoundException ex) {
- // A ClassNotFoundException here must be an IO error; wrap as such.
- throw new IOException(ex);
- }
- finally {
- jarInputStream.close();
- }
-
- return classes;
- }
-
- /**
- * Loads a list of classes, using the provided loading strategy.
- * @param classFileNames Which class files to load.
- * @param loader Dictates how these classes should be loaded.
- * @return A list of loaded classes.
- * @throws IOException In case there's an IO error trying to load the jar.
- */
- private static List loadClasses( List classFileNames, LoadingStrategy loader )
- throws IOException {
- List classes = new ArrayList();
-
- for (String classFileName : classFileNames) {
- String className = fileNameToClassName(classFileName);
- try {
- classes.add( loader.load( className ) );
- }
- catch (ClassNotFoundException ex) {
- // A ClassNotFoundException here must be an IO error; wrap as such.
- throw new IOException(ex);
- }
- }
-
- return classes;
- }
-
-
- /**
- * What mechanism should we use for loading a list of classes?
- */
- private static interface LoadingStrategy {
- Class load( String className ) throws ClassNotFoundException;
- }
-
- /**
- * An internal loading strategy, for loading classes already on the classpath.
- */
- private static class InternalLoadingStrategy implements LoadingStrategy {
- public Class load( String className )
- throws ClassNotFoundException {
- return Class.forName( className );
- }
- }
-
- /**
- * An external loading strategy, for loading classes not necessarily already
- * on the classpath.
- */
- private static class ExternalLoadingStrategy implements LoadingStrategy {
- private final ClassLoader classLoader;
-
- public ExternalLoadingStrategy( final File jarFile ) throws IOException {
- URL pathURL = jarFile.toURI().toURL();
- classLoader = new URLClassLoader(new URL[]{pathURL});
- }
-
- public Class load( String className ) throws ClassNotFoundException {
- return classLoader.loadClass(className);
- }
+ public static boolean isConcrete( Class clazz ) {
+ return !Modifier.isAbstract(clazz.getModifiers()) &&
+ !Modifier.isInterface(clazz.getModifiers());
}
}
diff --git a/java/src/org/broadinstitute/sting/utils/PackageUtils.java b/java/src/org/broadinstitute/sting/utils/PackageUtils.java
index cc99d630c..3ff474686 100755
--- a/java/src/org/broadinstitute/sting/utils/PackageUtils.java
+++ b/java/src/org/broadinstitute/sting/utils/PackageUtils.java
@@ -1,56 +1,55 @@
package org.broadinstitute.sting.utils;
-import java.util.List;
+import org.reflections.Reflections;
+import org.reflections.scanners.SubTypesScanner;
+import org.reflections.util.AbstractConfiguration;
+import org.reflections.util.ClasspathHelper;
+
+import java.util.Set;
import java.util.ArrayList;
-import java.io.File;
-import java.io.IOException;
+import java.util.List;
/**
* PackageUtils contains some useful methods for package introspection.
*/
public class PackageUtils {
+ /**
+ * A reference into our introspection utility.
+ */
+ private static Reflections reflections = null;
+
+ static {
+ // Initialize general-purpose source tree reflector.
+ reflections = new Reflections( new AbstractConfiguration() {
+ {
+ setUrls(ClasspathHelper.getUrlsForCurrentClasspath());
+ setScanners(new SubTypesScanner());
+ }
+ });
+ }
+
/**
* Private constructor. No instantiating this class!
*/
private PackageUtils() {}
+ {
+ }
/**
* Return the classes that implement the specified interface.
*
* @param iface the interface which returned classes should implement.
- * @return the list of classes that implement the interface. How is that not clear by now?!!!!111one!!
+ * @return the list of classes that implement the interface.
*/
- public static ArrayList getClassesImplementingInterface(Class iface) {
- try {
- final File location = JVMUtils.getLocationFor(iface);
-
- List potentialClasses = getClassesFromLocation(location);
- ArrayList implementingClasses = new ArrayList();
-
- for (Class potentialClass : potentialClasses) {
- if (JVMUtils.isConcreteImplementationOf(potentialClass, iface)) {
- implementingClasses.add(potentialClass);
- }
- }
-
- return implementingClasses;
- } catch (IOException e) {
- throw new StingException(String.format("Unable to inspect package containing '%s'", iface.getName()));
+ public static List> getClassesImplementingInterface(Class iface) {
+ // Load all classes implementing the given interface, then filter out any class that isn't concrete.
+ Set> allTypes = reflections.getSubTypesOf(iface);
+ List> concreteTypes = new ArrayList>();
+ for( Class extends T> type: allTypes ) {
+ if( JVMUtils.isConcrete(type) )
+ concreteTypes.add(type);
}
- }
- /**
- * Return a list of classes at the specified location
- * @param location the location where we should start searching (as returned by JVMUtils.getLocationFor(Class))
- * @return a list of classes at this location
- * @throws IOException thrown if the jar or directory cannot be inspected
- */
- public static List getClassesFromLocation(File location) throws IOException {
- if (location.getAbsolutePath().endsWith(".jar"))
- return JVMUtils.loadInternalClassesFromJar(location);
- else {
- List classFileNames = PathUtils.findFilesInPath(location, "", "class", true);
- return JVMUtils.loadInternalClasses(classFileNames);
- }
+ return concreteTypes;
}
}
diff --git a/java/src/org/broadinstitute/sting/utils/cmdLine/CommandLineProgram.java b/java/src/org/broadinstitute/sting/utils/cmdLine/CommandLineProgram.java
index 7a1eaf448..b9a00b590 100644
--- a/java/src/org/broadinstitute/sting/utils/cmdLine/CommandLineProgram.java
+++ b/java/src/org/broadinstitute/sting/utils/cmdLine/CommandLineProgram.java
@@ -99,13 +99,7 @@ public abstract class CommandLineProgram {
// Default implementation to find a command line that makes sense.
// If the user is running from a jar, return '-jar '; otherwise
// return the full class name.
- String runningInstructions = null;
- try {
- runningInstructions = JVMUtils.getLocationFor( getClass() ).getName();
- }
- catch( IOException ex ) {
- throw new StingException("Unable to determine running instructions", ex);
- }
+ String runningInstructions = getClass().getName();
if( runningInstructions.endsWith(".jar") )
runningInstructions = String.format("-jar %s", runningInstructions);
diff --git a/settings/ivysettings.xml b/settings/ivysettings.xml
index 5cacb105a..fcfc8fd0f 100644
--- a/settings/ivysettings.xml
+++ b/settings/ivysettings.xml
@@ -12,5 +12,6 @@
+
diff --git a/settings/repository/org.reflections/reflections-0.9.2.jar b/settings/repository/org.reflections/reflections-0.9.2.jar
new file mode 100644
index 000000000..c91cffea5
Binary files /dev/null and b/settings/repository/org.reflections/reflections-0.9.2.jar differ
diff --git a/settings/repository/org.reflections/reflections-0.9.2.xml b/settings/repository/org.reflections/reflections-0.9.2.xml
new file mode 100644
index 000000000..7676d4df8
--- /dev/null
+++ b/settings/repository/org.reflections/reflections-0.9.2.xml
@@ -0,0 +1,3 @@
+
+
+