Lazy loading reflections so Queue can hack the classpath before the PluginManager looks for classes.
Removed extra quotes from 'cd' pre-exec command. git-svn-id: file:///humgen/gsa-scr1/gsa-engineering/svn_contents/trunk@4067 348d0f76-0448-11de-a6fe-93d51630548a
This commit is contained in:
parent
0028b884d8
commit
88ca1fb22c
|
|
@ -35,7 +35,9 @@ import org.reflections.util.ClasspathHelper;
|
||||||
import org.reflections.util.ConfigurationBuilder;
|
import org.reflections.util.ConfigurationBuilder;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
@ -54,11 +56,6 @@ public class PackageUtils {
|
||||||
// turn off logging in the reflections library - they talk too much (to the wrong logger factory as well, logback)
|
// turn off logging in the reflections library - they talk too much (to the wrong logger factory as well, logback)
|
||||||
Logger logger = (ch.qos.logback.classic.Logger)LoggerFactory.getLogger(Reflections.class);
|
Logger logger = (ch.qos.logback.classic.Logger)LoggerFactory.getLogger(Reflections.class);
|
||||||
logger.setLevel(Level.OFF);
|
logger.setLevel(Level.OFF);
|
||||||
|
|
||||||
// Initialize general-purpose source tree reflector.
|
|
||||||
reflections = new Reflections( new ConfigurationBuilder()
|
|
||||||
.setUrls(getClassPathURLs())
|
|
||||||
.setScanners(new SubTypesScanner()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -76,6 +73,7 @@ public class PackageUtils {
|
||||||
*/
|
*/
|
||||||
public static <T> List<Class<? extends T>> getClassesImplementingInterface(Class<T> iface) {
|
public static <T> List<Class<? extends T>> getClassesImplementingInterface(Class<T> iface) {
|
||||||
// Load all classes implementing the given interface, then filter out any class that isn't concrete.
|
// Load all classes implementing the given interface, then filter out any class that isn't concrete.
|
||||||
|
initReflections();
|
||||||
Set<Class<? extends T>> allTypes = reflections.getSubTypesOf(iface);
|
Set<Class<? extends T>> allTypes = reflections.getSubTypesOf(iface);
|
||||||
List<Class<? extends T>> concreteTypes = new ArrayList<Class<? extends T>>();
|
List<Class<? extends T>> concreteTypes = new ArrayList<Class<? extends T>>();
|
||||||
for( Class<? extends T> type: allTypes ) {
|
for( Class<? extends T> type: allTypes ) {
|
||||||
|
|
@ -112,6 +110,7 @@ public class PackageUtils {
|
||||||
*/
|
*/
|
||||||
public static <T> List<Class<? extends T>> getInterfacesExtendingInterface(Class<T> iface) {
|
public static <T> List<Class<? extends T>> getInterfacesExtendingInterface(Class<T> iface) {
|
||||||
// Load all classes extending the given interface, then filter out any class that is concrete.
|
// Load all classes extending the given interface, then filter out any class that is concrete.
|
||||||
|
initReflections();
|
||||||
Set<Class<? extends T>> allTypes = reflections.getSubTypesOf(iface);
|
Set<Class<? extends T>> allTypes = reflections.getSubTypesOf(iface);
|
||||||
List<Class<? extends T>> nonConcreteTypes = new ArrayList<Class<? extends T>>();
|
List<Class<? extends T>> nonConcreteTypes = new ArrayList<Class<? extends T>>();
|
||||||
for( Class<? extends T> type: allTypes ) {
|
for( Class<? extends T> type: allTypes ) {
|
||||||
|
|
@ -125,4 +124,40 @@ public class PackageUtils {
|
||||||
public static Set<URL> getClassPathURLs() {
|
public static Set<URL> getClassPathURLs() {
|
||||||
return ClasspathHelper.getUrlsForManifestsCurrentClasspath();
|
return ClasspathHelper.getUrlsForManifestsCurrentClasspath();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the URL to the system class loader classpath using reflection.
|
||||||
|
* HACK: Uses reflection to modify the class path, and assumes loader is a URLClassLoader.
|
||||||
|
* @param url URL to add to the system class loader classpath.
|
||||||
|
*/
|
||||||
|
public static void addClasspath(URL url) {
|
||||||
|
try {
|
||||||
|
Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
|
||||||
|
if (!method.isAccessible())
|
||||||
|
method.setAccessible(true);
|
||||||
|
method.invoke(ClassLoader.getSystemClassLoader(), url);
|
||||||
|
resetReflections();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new StingException("Error adding url to the current classloader.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create new reflections object if it does not currently exists.
|
||||||
|
*/
|
||||||
|
private static void initReflections() {
|
||||||
|
if (reflections == null) {
|
||||||
|
// Initialize general-purpose source tree reflector.
|
||||||
|
reflections = new Reflections( new ConfigurationBuilder()
|
||||||
|
.setUrls(getClassPathURLs())
|
||||||
|
.setScanners(new SubTypesScanner()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the reflections object after a class has been dynamically added to the classpath.
|
||||||
|
*/
|
||||||
|
private static void resetReflections() {
|
||||||
|
reflections = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,15 @@
|
||||||
package org.broadinstitute.sting.queue
|
package org.broadinstitute.sting.queue
|
||||||
|
|
||||||
import org.broadinstitute.sting.utils.classloader.PluginManager
|
|
||||||
import scala.tools.nsc.{Global, Settings}
|
import scala.tools.nsc.{Global, Settings}
|
||||||
import scala.tools.nsc.io.PlainFile
|
import scala.tools.nsc.io.PlainFile
|
||||||
import org.broadinstitute.sting.queue.util.{Logging, ClasspathUtils, IOUtils}
|
import org.broadinstitute.sting.queue.util.{Logging, IOUtils}
|
||||||
import collection.JavaConversions
|
import collection.JavaConversions
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import scala.tools.nsc.reporters.AbstractReporter
|
import scala.tools.nsc.reporters.AbstractReporter
|
||||||
import java.lang.String
|
import java.lang.String
|
||||||
import org.apache.log4j.Level
|
import org.apache.log4j.Level
|
||||||
import scala.tools.nsc.util.{FakePos, NoPosition, Position}
|
import scala.tools.nsc.util.{FakePos, NoPosition, Position}
|
||||||
|
import org.broadinstitute.sting.utils.classloader.{PackageUtils, PluginManager}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Plugin manager for QScripts which loads QScripts into the current class loader.
|
* Plugin manager for QScripts which loads QScripts into the current class loader.
|
||||||
|
|
@ -52,7 +52,7 @@ object QScriptManager extends Logging {
|
||||||
settings.outdir.value = outdir.getPath
|
settings.outdir.value = outdir.getPath
|
||||||
|
|
||||||
// Set the classpath to the current class path.
|
// Set the classpath to the current class path.
|
||||||
ClasspathUtils.manifestAwareClassPath.foreach(path => settings.classpath.append(path.getPath))
|
JavaConversions.asSet(PackageUtils.getClassPathURLs).foreach(url => settings.classpath.append(url.getPath))
|
||||||
|
|
||||||
val reporter = new Log4JReporter(settings)
|
val reporter = new Log4JReporter(settings)
|
||||||
|
|
||||||
|
|
@ -76,7 +76,7 @@ object QScriptManager extends Logging {
|
||||||
logger.info("Compilation complete")
|
logger.info("Compilation complete")
|
||||||
|
|
||||||
// Add the new compilation output directory to the classpath.
|
// Add the new compilation output directory to the classpath.
|
||||||
ClasspathUtils.addClasspath(outdir)
|
PackageUtils.addClasspath(outdir.toURI.toURL)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ trait DispatchJobRunner extends JobRunner {
|
||||||
for (dir <- function.jobDirectories)
|
for (dir <- function.jobDirectories)
|
||||||
dirs += IOUtils.dirLevel(dir, 2)
|
dirs += IOUtils.dirLevel(dir, 2)
|
||||||
if (dirs.size > 0)
|
if (dirs.size > 0)
|
||||||
Some("\'" + dirs.mkString("cd ", " && cd ", "") + "\'")
|
Some(dirs.mkString("cd ", " && cd ", ""))
|
||||||
else
|
else
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
package org.broadinstitute.sting.queue.util
|
|
||||||
|
|
||||||
import collection.JavaConversions._
|
|
||||||
import org.broadinstitute.sting.utils.classloader.PackageUtils
|
|
||||||
import java.io.File
|
|
||||||
import javax.print.URIException
|
|
||||||
import java.net.{URL, URLClassLoader}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Builds the correct class path by examining the manifests
|
|
||||||
*/
|
|
||||||
object ClasspathUtils {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a list of files that build up the classpath, taking into account jar file manifests.
|
|
||||||
* @return List[File] that build up the current classpath.
|
|
||||||
*/
|
|
||||||
def manifestAwareClassPath = {
|
|
||||||
var urls = PackageUtils.getClassPathURLs
|
|
||||||
urls.map(url => try {new File(url.toURI)} catch {case urie: URIException => new File(url.getPath)})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds the directory to the system class loader classpath using reflection.
|
|
||||||
* HACK: Uses reflection to modify the class path, and assumes loader is a URLClassLoader
|
|
||||||
* @param path Directory to add to the system class loader classpath.
|
|
||||||
*/
|
|
||||||
def addClasspath(path: File): Unit = {
|
|
||||||
val url = path.toURI.toURL
|
|
||||||
val method = classOf[URLClassLoader].getDeclaredMethod("addURL", classOf[URL]);
|
|
||||||
if (!method.isAccessible)
|
|
||||||
method.setAccessible(true);
|
|
||||||
method.invoke(ClassLoader.getSystemClassLoader(), url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Loading…
Reference in New Issue