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:
kshakir 2010-08-19 20:29:52 +00:00
parent 0028b884d8
commit 88ca1fb22c
4 changed files with 45 additions and 46 deletions

View File

@ -35,7 +35,9 @@ import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Set;
import java.util.ArrayList;
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)
Logger logger = (ch.qos.logback.classic.Logger)LoggerFactory.getLogger(Reflections.class);
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) {
// 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);
List<Class<? extends T>> concreteTypes = new ArrayList<Class<? extends T>>();
for( Class<? extends T> type: allTypes ) {
@ -112,6 +110,7 @@ public class PackageUtils {
*/
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.
initReflections();
Set<Class<? extends T>> allTypes = reflections.getSubTypesOf(iface);
List<Class<? extends T>> nonConcreteTypes = new ArrayList<Class<? extends T>>();
for( Class<? extends T> type: allTypes ) {
@ -125,4 +124,40 @@ public class PackageUtils {
public static Set<URL> getClassPathURLs() {
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;
}
}

View File

@ -1,15 +1,15 @@
package org.broadinstitute.sting.queue
import org.broadinstitute.sting.utils.classloader.PluginManager
import scala.tools.nsc.{Global, Settings}
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 java.io.File
import scala.tools.nsc.reporters.AbstractReporter
import java.lang.String
import org.apache.log4j.Level
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.
@ -52,7 +52,7 @@ object QScriptManager extends Logging {
settings.outdir.value = outdir.getPath
// 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)
@ -76,7 +76,7 @@ object QScriptManager extends Logging {
logger.info("Compilation complete")
// Add the new compilation output directory to the classpath.
ClasspathUtils.addClasspath(outdir)
PackageUtils.addClasspath(outdir.toURI.toURL)
}
}

View File

@ -64,7 +64,7 @@ trait DispatchJobRunner extends JobRunner {
for (dir <- function.jobDirectories)
dirs += IOUtils.dirLevel(dir, 2)
if (dirs.size > 0)
Some("\'" + dirs.mkString("cd ", " && cd ", "") + "\'")
Some(dirs.mkString("cd ", " && cd ", ""))
else
None
}

View File

@ -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);
}
}