mirror of https://github.com/sbt/sbt.git
Merge pull request #2214 from twitter-forks/stuhood/more-thorough-classfile-location-detection
More thorough classfile location detection
This commit is contained in:
commit
33478132c5
|
|
@ -160,7 +160,7 @@ object ClassToAPI {
|
||||||
} catch {
|
} catch {
|
||||||
case e: Throwable =>
|
case e: Throwable =>
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
s"Failed to parse class $c: this may mean your classfiles are corrupted. Please clean and try again.",
|
s"Failed to parse $c: this may mean your classfiles are corrupted. Please clean and try again.",
|
||||||
e
|
e
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,14 +38,23 @@ object IO {
|
||||||
/**
|
/**
|
||||||
* Returns a URL for the directory or jar containing the the class file `cl`.
|
* Returns a URL for the directory or jar containing the the class file `cl`.
|
||||||
* If the location cannot be determined, an error is generated.
|
* If the location cannot be determined, an error is generated.
|
||||||
* Note that Java standard library classes typically do not have a location associated with them.
|
|
||||||
*/
|
*/
|
||||||
def classLocation(cl: Class[_]): URL =
|
def classLocation(cl: Class[_]): URL = {
|
||||||
{
|
val codeSource = cl.getProtectionDomain.getCodeSource
|
||||||
val codeSource = cl.getProtectionDomain.getCodeSource
|
if (codeSource ne null) {
|
||||||
if (codeSource == null) sys.error("No class location for " + cl)
|
codeSource.getLocation
|
||||||
else codeSource.getLocation
|
} else {
|
||||||
|
// NB: This assumes that classes without code sources are System classes, and thus located in
|
||||||
|
// jars. It assumes that `urlAsFile` will truncate to the containing jar file.
|
||||||
|
val clsfile = s"${cl.getName.replace('.', '/')}.class"
|
||||||
|
Option(ClassLoader.getSystemClassLoader.getResource(clsfile))
|
||||||
|
.flatMap {
|
||||||
|
urlAsFile
|
||||||
|
}.getOrElse {
|
||||||
|
sys.error("No class location for " + cl)
|
||||||
|
}.toURI.toURL
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the directory or jar file containing the the class file `cl`.
|
* Returns the directory or jar file containing the the class file `cl`.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
package sbt
|
||||||
|
|
||||||
|
import util.Try
|
||||||
|
|
||||||
|
import org.scalacheck._
|
||||||
|
import Prop._
|
||||||
|
|
||||||
|
object IOSpecification extends Properties("IO") {
|
||||||
|
property("classLocation able to determine containing directories") =
|
||||||
|
Prop.forAll(classes) { (c: Class[_]) =>
|
||||||
|
Try(IO.classLocationFile(c)).toOption.exists {
|
||||||
|
case jar if jar.getName.endsWith(".jar") => jar.isFile
|
||||||
|
case dir => dir.isDirectory
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
implicit def classes: Gen[Class[_]] =
|
||||||
|
Gen.oneOf(
|
||||||
|
this.getClass,
|
||||||
|
classOf[java.lang.Integer],
|
||||||
|
classOf[String],
|
||||||
|
classOf[Thread],
|
||||||
|
classOf[Properties]
|
||||||
|
)
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue