From d09aab03be50866422d8e44f9e9d047054784034 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 15 Apr 2011 18:22:57 -0400 Subject: [PATCH] better location for class loaders (ClassLoaders.scala) --- util/classpath/ClassLoaders.scala | 87 +++++++++++++++++++++++++ util/classpath/ClasspathUtilities.scala | 86 ------------------------ 2 files changed, 87 insertions(+), 86 deletions(-) diff --git a/util/classpath/ClassLoaders.scala b/util/classpath/ClassLoaders.scala index af3c039b5..d12283c05 100644 --- a/util/classpath/ClassLoaders.scala +++ b/util/classpath/ClassLoaders.scala @@ -41,4 +41,91 @@ class SelfFirstLoader(classpath: Seq[URL], parent: ClassLoader) extends LoaderBa try { findClass(className) } catch { case _: ClassNotFoundException => defaultLoadClass(className) } } +} + + +private class IntermediateLoader(urls: Array[URL], parent: ClassLoader) extends LoaderBase(urls, parent) +{ + def doLoadClass(className: String): Class[_] = + { + // if this loader is asked to load an sbt class, it must be because the project we are building is sbt itself, + // so we want to load the version of classes on the project classpath, not the parent + if(className.startsWith(Loaders.SbtPackage)) + findClass(className) + else + defaultLoadClass(className) + } +} +/** Delegates class loading to `parent` for all classes included by `filter`. An attempt to load classes excluded by `filter` +* results in a `ClassNotFoundException`.*/ +class FilteredLoader(parent: ClassLoader, filter: ClassFilter) extends ClassLoader(parent) +{ + require(parent != null) // included because a null parent is legitimate in Java + def this(parent: ClassLoader, excludePackages: Iterable[String]) = this(parent, new ExcludePackagesFilter(excludePackages)) + + @throws(classOf[ClassNotFoundException]) + override final def loadClass(className: String, resolve: Boolean): Class[_] = + { + if(filter.include(className)) + super.loadClass(className, resolve) + else + throw new ClassNotFoundException(className) + } +} +private class SelectiveLoader(urls: Array[URL], parent: ClassLoader, filter: ClassFilter) extends URLClassLoader(urls, parent) +{ + require(parent != null) // included because a null parent is legitimate in Java + def this(urls: Array[URL], parent: ClassLoader, includePackages: Iterable[String]) = this(urls, parent, new IncludePackagesFilter(includePackages)) + + @throws(classOf[ClassNotFoundException]) + override final def loadClass(className: String, resolve: Boolean): Class[_] = + { + if(filter.include(className)) + super.loadClass(className, resolve) + else + { + val loaded = parent.loadClass(className) + if(resolve) + resolveClass(loaded) + loaded + } + } +} +trait ClassFilter +{ + def include(className: String): Boolean +} +abstract class PackageFilter(packages: Iterable[String]) extends ClassFilter +{ + require(packages.forall(_.endsWith("."))) + protected final def matches(className: String): Boolean = packages.exists(className.startsWith) +} +class ExcludePackagesFilter(exclude: Iterable[String]) extends PackageFilter(exclude) +{ + def include(className: String): Boolean = !matches(className) +} +class IncludePackagesFilter(include: Iterable[String]) extends PackageFilter(include) +{ + def include(className: String): Boolean = matches(className) +} + +private[sbt] class LazyFrameworkLoader(runnerClassName: String, urls: Array[URL], parent: ClassLoader, grandparent: ClassLoader) + extends LoaderBase(urls, parent) +{ + def doLoadClass(className: String): Class[_] = + { + if(Loaders.isNestedOrSelf(className, runnerClassName)) + findClass(className) + else if(Loaders.isSbtClass(className)) // we circumvent the parent loader because we know that we want the + grandparent.loadClass(className) // version of sbt that is currently the builder (not the project being built) + else + parent.loadClass(className) + } +} +private object Loaders +{ + val SbtPackage = "sbt." + def isNestedOrSelf(className: String, checkAgainst: String) = + className == checkAgainst || className.startsWith(checkAgainst + "$") + def isSbtClass(className: String) = className.startsWith(Loaders.SbtPackage) } \ No newline at end of file diff --git a/util/classpath/ClasspathUtilities.scala b/util/classpath/ClasspathUtilities.scala index e5394e63b..9c6e940f4 100644 --- a/util/classpath/ClasspathUtilities.scala +++ b/util/classpath/ClasspathUtilities.scala @@ -129,89 +129,3 @@ object ClasspathUtilities set } } - -private class IntermediateLoader(urls: Array[URL], parent: ClassLoader) extends LoaderBase(urls, parent) -{ - def doLoadClass(className: String): Class[_] = - { - // if this loader is asked to load an sbt class, it must be because the project we are building is sbt itself, - // so we want to load the version of classes on the project classpath, not the parent - if(className.startsWith(Loaders.SbtPackage)) - findClass(className) - else - defaultLoadClass(className) - } -} -/** Delegates class loading to `parent` for all classes included by `filter`. An attempt to load classes excluded by `filter` -* results in a `ClassNotFoundException`.*/ -class FilteredLoader(parent: ClassLoader, filter: ClassFilter) extends ClassLoader(parent) -{ - require(parent != null) // included because a null parent is legitimate in Java - def this(parent: ClassLoader, excludePackages: Iterable[String]) = this(parent, new ExcludePackagesFilter(excludePackages)) - - @throws(classOf[ClassNotFoundException]) - override final def loadClass(className: String, resolve: Boolean): Class[_] = - { - if(filter.include(className)) - super.loadClass(className, resolve) - else - throw new ClassNotFoundException(className) - } -} -private class SelectiveLoader(urls: Array[URL], parent: ClassLoader, filter: ClassFilter) extends URLClassLoader(urls, parent) -{ - require(parent != null) // included because a null parent is legitimate in Java - def this(urls: Array[URL], parent: ClassLoader, includePackages: Iterable[String]) = this(urls, parent, new IncludePackagesFilter(includePackages)) - - @throws(classOf[ClassNotFoundException]) - override final def loadClass(className: String, resolve: Boolean): Class[_] = - { - if(filter.include(className)) - super.loadClass(className, resolve) - else - { - val loaded = parent.loadClass(className) - if(resolve) - resolveClass(loaded) - loaded - } - } -} -trait ClassFilter -{ - def include(className: String): Boolean -} -abstract class PackageFilter(packages: Iterable[String]) extends ClassFilter -{ - require(packages.forall(_.endsWith("."))) - protected final def matches(className: String): Boolean = packages.exists(className.startsWith) -} -class ExcludePackagesFilter(exclude: Iterable[String]) extends PackageFilter(exclude) -{ - def include(className: String): Boolean = !matches(className) -} -class IncludePackagesFilter(include: Iterable[String]) extends PackageFilter(include) -{ - def include(className: String): Boolean = matches(className) -} - -private[sbt] class LazyFrameworkLoader(runnerClassName: String, urls: Array[URL], parent: ClassLoader, grandparent: ClassLoader) - extends LoaderBase(urls, parent) -{ - def doLoadClass(className: String): Class[_] = - { - if(Loaders.isNestedOrSelf(className, runnerClassName)) - findClass(className) - else if(Loaders.isSbtClass(className)) // we circumvent the parent loader because we know that we want the - grandparent.loadClass(className) // version of sbt that is currently the builder (not the project being built) - else - parent.loadClass(className) - } -} -private object Loaders -{ - val SbtPackage = "sbt." - def isNestedOrSelf(className: String, checkAgainst: String) = - className == checkAgainst || className.startsWith(checkAgainst + "$") - def isSbtClass(className: String) = className.startsWith(Loaders.SbtPackage) -} \ No newline at end of file