aboutsummaryrefslogtreecommitdiff
path: root/libraries
diff options
context:
space:
mode:
authorKoert Kuipers <koert@tresata.com>2013-05-07 18:04:33 +0000
committerChristopher Vogt <oss.nsp@cvogt.org>2016-11-07 02:08:38 -0500
commite266ed31eab5fc1aac4d7d7d9d7a0c3c4fe5daee (patch)
treea0e503ca1352bd0665def1ce4fcb52050532ff6d /libraries
parent90a4eb50a31888a669511cb7cac11328cce8ebf7 (diff)
downloadcbt-e266ed31eab5fc1aac4d7d7d9d7a0c3c4fe5daee.tar.gz
cbt-e266ed31eab5fc1aac4d7d7d9d7a0c3c4fe5daee.tar.bz2
cbt-e266ed31eab5fc1aac4d7d7d9d7a0c3c4fe5daee.zip
[split] util-eval: fix for when class files are on the classpath directly
fix for when scala.tool.nsc.Interpreter and scala.ScalaObject class files are on the classpath directly instead of in jar. fix for when multiple class loaders are used. i needed both these fixes to use Eval with 'hadoop jar' and a fat jar since hadoop unpacks the jar to a temporary directory and puts the class files directly on the classpath by introducing a new class loader Signed-off-by: Rao Fu <rao@twitter.com> RB_ID=142194
Diffstat (limited to 'libraries')
-rw-r--r--libraries/eval/Eval.scala35
1 files changed, 26 insertions, 9 deletions
diff --git a/libraries/eval/Eval.scala b/libraries/eval/Eval.scala
index 07f684c..33980cf 100644
--- a/libraries/eval/Eval.scala
+++ b/libraries/eval/Eval.scala
@@ -71,14 +71,14 @@ class Eval(target: Option[File]) {
import Eval.jvmId
private lazy val compilerPath = try {
- jarPathOfClass("scala.tools.nsc.Interpreter")
+ classPathOfClass("scala.tools.nsc.Interpreter")
} catch {
case e =>
throw new RuntimeException("Unable lo load scala interpreter from classpath (scala-compiler jar is missing?)", e)
}
private lazy val libPath = try {
- jarPathOfClass("scala.ScalaObject")
+ classPathOfClass("scala.ScalaObject")
} catch {
case e =>
throw new RuntimeException("Unable to load scala base object from classpath (scala-library jar is missing?)", e)
@@ -301,12 +301,17 @@ class Eval(target: Option[File]) {
/*
* For a given FQ classname, trick the resource finder into telling us the containing jar.
*/
- private def jarPathOfClass(className: String) = try {
+ private def classPathOfClass(className: String) = try {
val resource = className.split('.').mkString("/", "/", ".class")
val path = getClass.getResource(resource).getPath
- val indexOfFile = path.indexOf("file:") + 5
- val indexOfSeparator = path.lastIndexOf('!')
- List(path.substring(indexOfFile, indexOfSeparator))
+ if (path.indexOf("file:") >= 0) {
+ val indexOfFile = path.indexOf("file:") + 5
+ val indexOfSeparator = path.lastIndexOf('!')
+ List(path.substring(indexOfFile, indexOfSeparator))
+ } else {
+ require(path.endsWith(resource))
+ List(path.substring(0, path.length - resource.length + 1))
+ }
}
/*
@@ -314,8 +319,20 @@ class Eval(target: Option[File]) {
* This is probably fragile.
*/
lazy val impliedClassPath: List[String] = {
- val currentClassPath = this.getClass.getClassLoader.asInstanceOf[URLClassLoader].getURLs.
- filter(_.getProtocol == "file").map(u => new File(u.toURI).getPath).toList
+ def getClassPath(cl: ClassLoader, acc: List[List[String]] = List.empty): List[List[String]] = {
+ val cp = cl match {
+ case urlClassLoader: URLClassLoader => urlClassLoader.getURLs.filter(_.getProtocol == "file").
+ map(u => new File(u.toURI).getPath).toList
+ case _ => Nil
+ }
+ cl.getParent match {
+ case null => (cp :: acc).reverse
+ case parent => getClassPath(parent, cp :: acc)
+ }
+ }
+
+ val classPath = getClassPath(this.getClass.getClassLoader)
+ val currentClassPath = classPath.head
// if there's just one thing in the classpath, and it's a jar, assume an executable jar.
currentClassPath ::: (if (currentClassPath.size == 1 && currentClassPath(0).endsWith(".jar")) {
@@ -329,7 +346,7 @@ class Eval(target: Option[File]) {
}
} else {
Nil
- })
+ }) ::: classPath.tail.flatten
}
trait Preprocessor {