mirror of https://github.com/sbt/sbt.git
class loader extension to handle native libraries loaded in multiple class loaders
This commit is contained in:
parent
f065037572
commit
7ea35daec2
|
|
@ -128,4 +128,35 @@ private object Loaders
|
|||
def isNestedOrSelf(className: String, checkAgainst: String) =
|
||||
className == checkAgainst || className.startsWith(checkAgainst + "$")
|
||||
def isSbtClass(className: String) = className.startsWith(Loaders.SbtPackage)
|
||||
}
|
||||
|
||||
final class NativeCopyConfig(val tempDirectory: File, val explicitLibraries: Seq[File], val searchPaths: Seq[File])
|
||||
trait NativeCopyLoader extends ClassLoader
|
||||
{
|
||||
protected val config: NativeCopyConfig
|
||||
import config._
|
||||
|
||||
private[this] val mapped = new collection.mutable.HashMap[String, String]
|
||||
|
||||
override protected def findLibrary(name: String): String =
|
||||
synchronized { mapped.getOrElseUpdate(name, findLibrary0(name)) }
|
||||
|
||||
private[this] def findLibrary0(name: String): String =
|
||||
{
|
||||
val mappedName = System.mapLibraryName(name)
|
||||
val explicit = explicitLibraries.filter(_.getName == mappedName).toStream
|
||||
val search = searchPaths.toStream flatMap relativeLibrary(mappedName)
|
||||
(explicit ++ search).headOption.map(copy).orNull
|
||||
}
|
||||
private[this] def relativeLibrary(mappedName: String)(base: File): Seq[File] =
|
||||
{
|
||||
val f = new File(base, mappedName)
|
||||
if(f.isFile) f :: Nil else Nil
|
||||
}
|
||||
private[this] def copy(f: File): String =
|
||||
{
|
||||
val target = new File(tempDirectory, f.getName)
|
||||
IO.copyFile(f, target)
|
||||
target.getAbsolutePath
|
||||
}
|
||||
}
|
||||
|
|
@ -22,7 +22,13 @@ object ClasspathUtilities
|
|||
|
||||
def toLoader(paths: Seq[File], parent: ClassLoader, resourceMap: Map[String,String]): ClassLoader =
|
||||
new URLClassLoader(Path.toURLs(paths), parent) with RawResources { override def resources = resourceMap }
|
||||
|
||||
|
||||
def toLoader(paths: Seq[File], parent: ClassLoader, resourceMap: Map[String,String], nativeTemp: File): ClassLoader =
|
||||
new URLClassLoader(Path.toURLs(paths), parent) with RawResources with NativeCopyLoader {
|
||||
override def resources = resourceMap
|
||||
override val config = new NativeCopyConfig(nativeTemp, paths, Nil)
|
||||
}
|
||||
|
||||
lazy val rootLoader =
|
||||
{
|
||||
def parent(loader: ClassLoader): ClassLoader =
|
||||
|
|
@ -50,6 +56,9 @@ object ClasspathUtilities
|
|||
|
||||
def makeLoader[T](classpath: Seq[File], parent: ClassLoader, instance: ScalaInstance): ClassLoader =
|
||||
toLoader(classpath, parent, createClasspathResources(classpath, instance))
|
||||
|
||||
def makeLoader[T](classpath: Seq[File], parent: ClassLoader, instance: ScalaInstance, nativeTemp: File): ClassLoader =
|
||||
toLoader(classpath, parent, createClasspathResources(classpath, instance), nativeTemp)
|
||||
|
||||
private[sbt] def printSource(c: Class[_]) =
|
||||
println(c.getName + " loader=" +c.getClassLoader + " location=" + IO.classLocationFile(c))
|
||||
|
|
|
|||
Loading…
Reference in New Issue