From b408b441569dc165f4d41b048ff64253695a491d Mon Sep 17 00:00:00 2001 From: Christopher Vogt Date: Wed, 9 Mar 2016 01:48:09 -0500 Subject: Add feature for starting the Scala REPL in arbitrary versions, propagate logger as implicits --- stage1/Stage1.scala | 6 ++++-- stage1/resolver.scala | 38 ++++++++++++++++++++++---------------- 2 files changed, 26 insertions(+), 18 deletions(-) (limited to 'stage1') diff --git a/stage1/Stage1.scala b/stage1/Stage1.scala index 1aa3f09..7702678 100644 --- a/stage1/Stage1.scala +++ b/stage1/Stage1.scala @@ -67,14 +67,16 @@ abstract class Stage1Base{ logger.stage1("before conditionally running zinc to recompile CBT") if( src.exists(newerThan(_, changeIndicator)) ) { - val stage1Classpath = CbtDependency(logger).dependencyClasspath + val stage1Classpath = CbtDependency()(logger).dependencyClasspath logger.stage1("cbt.lib has changed. Recompiling with cp: " ++ stage1Classpath.string) zinc( true, src, stage2Target, stage1Classpath )( zincVersion = "0.3.9", scalaVersion = constants.scalaVersion ) } logger.stage1(s"[$now] calling CbtDependency.classLoader") logger.stage1(s"[$now] Run Stage2") - val ExitCode(exitCode) = runMain( mainClass, cwd +: args.drop(1).toVector, CbtDependency(logger).classLoader ) + val ExitCode(exitCode) = /*trapExitCode*/{ // this + runMain( mainClass, cwd +: args.drop(1).toVector, CbtDependency()(logger).classLoader ) + } logger.stage1(s"[$now] Stage1 end") System.exit(exitCode) } diff --git a/stage1/resolver.scala b/stage1/resolver.scala index fae5e9d..30f03e2 100644 --- a/stage1/resolver.scala +++ b/stage1/resolver.scala @@ -32,12 +32,13 @@ abstract class Dependency{ def exportedJars: Seq[File] def jars: Seq[File] = exportedJars ++ dependencyJars + def canBeCached = false def cacheDependencyClassLoader = true private object cacheClassLoaderBasicBuild extends Cache[URLClassLoader] def classLoader: URLClassLoader = cacheClassLoaderBasicBuild{ val transitiveClassPath = transitiveDependencies.map{ - case d: MavenDependency => Left(d) + case d if d.canBeCached => Left(d) case d => Right(d) } val buildClassPath = ClassPath.flatten( @@ -95,35 +96,39 @@ abstract class Dependency{ } // TODO: all this hard codes the scala version, needs more flexibility -class ScalaCompiler(logger: Logger) extends MavenDependency("org.scala-lang","scala-compiler",constants.scalaVersion)(logger) -class ScalaLibrary(logger: Logger) extends MavenDependency("org.scala-lang","scala-library",constants.scalaVersion)(logger) -class ScalaReflect(logger: Logger) extends MavenDependency("org.scala-lang","scala-reflect",constants.scalaVersion)(logger) +class ScalaCompilerDependency(version: String)(implicit logger: Logger) extends MavenDependency("org.scala-lang","scala-compiler",version) +class ScalaLibraryDependency (version: String)(implicit logger: Logger) extends MavenDependency("org.scala-lang","scala-library",version) +class ScalaReflectDependency (version: String)(implicit logger: Logger) extends MavenDependency("org.scala-lang","scala-reflect",version) -case class ScalaDependencies(logger: Logger) extends Dependency{ +case class ScalaDependencies(version: String)(implicit val logger: Logger) extends Dependency{ sd => + final val updated = false + override def canBeCached = true def exportedClasspath = ClassPath(Seq()) def exportedJars = Seq[File]() - def dependencies = Seq( new ScalaCompiler(logger), new ScalaLibrary(logger), new ScalaReflect(logger) ) - final val updated = false + def dependencies = Seq( + new ScalaCompilerDependency(version)(logger), + new ScalaLibraryDependency(version)(logger), + new ScalaReflectDependency(version)(logger) + ) } -/* -case class BinaryDependency( path: File, dependencies: Seq[Dependency] ) extends Dependency{ +case class BinaryDependency( path: File, dependencies: Seq[Dependency] )(implicit val logger: Logger) extends Dependency{ + def updated = false def exportedClasspath = ClassPath(Seq(path)) - def exportedJars = Seq[File]() + def exportedJars = Seq[File](path) } -*/ -case class Stage1Dependency(logger: Logger) extends Dependency{ +case class Stage1Dependency()(implicit val logger: Logger) extends Dependency{ def exportedClasspath = ClassPath( Seq(nailgunTarget, stage1Target) ) def exportedJars = Seq[File]() - def dependencies = ScalaDependencies(logger: Logger).dependencies + def dependencies = ScalaDependencies(constants.scalaVersion).dependencies def updated = false // FIXME: think this through, might allow simplifications and/or optimizations } -case class CbtDependency(logger: Logger) extends Dependency{ +case class CbtDependency()(implicit val logger: Logger) extends Dependency{ def exportedClasspath = ClassPath( Seq( stage2Target ) ) def exportedJars = Seq[File]() override def dependencies = Seq( - Stage1Dependency(logger), + Stage1Dependency()(logger), MavenDependency("net.incongru.watchservice","barbary-watchservice","1.0")(logger), MavenDependency("com.lihaoyi","ammonite-repl_2.11.7","0.5.5")(logger), MavenDependency("org.scala-lang.modules","scala-xml_2.11","1.0.5")(logger) @@ -136,10 +141,11 @@ final case class Classifier(name: String) extends ClassifierBase case object javadoc extends ClassifierBase case object sources extends ClassifierBase -case class MavenDependency( groupId: String, artifactId: String, version: String, sources: Boolean = false )(val logger: Logger) +case class MavenDependency( groupId: String, artifactId: String, version: String, sources: Boolean = false )(implicit val logger: Logger) extends ArtifactInfo{ def updated = false + override def canBeCached = true private val groupPath = groupId.split("\\.").mkString("/") def basePath = s"/$groupPath/$artifactId/$version/$artifactId-$version"++(if(sources) "-sources" else "") -- cgit v1.2.3 From 984a5f1f0f27d191695feeb3410968f2f35f8fc8 Mon Sep 17 00:00:00 2001 From: Christopher Vogt Date: Fri, 11 Mar 2016 22:36:31 -0500 Subject: Split ClassLoader classes into separate files and a few fixes --- stage1/ClassLoaderCache.scala | 25 +++++++++++++++++ stage1/MultiClassLoader.scala | 24 ++++++++++++++++ stage1/Stage1Lib.scala | 8 ++++++ stage1/URLClassLoader.scala | 22 +++++++++++++++ stage1/classloader.scala | 64 ------------------------------------------- stage2/BasicBuild.scala | 4 +-- test/build/build.scala | 7 +++-- 7 files changed, 85 insertions(+), 69 deletions(-) create mode 100644 stage1/ClassLoaderCache.scala create mode 100644 stage1/MultiClassLoader.scala create mode 100644 stage1/URLClassLoader.scala delete mode 100644 stage1/classloader.scala (limited to 'stage1') diff --git a/stage1/ClassLoaderCache.scala b/stage1/ClassLoaderCache.scala new file mode 100644 index 0000000..ec343f4 --- /dev/null +++ b/stage1/ClassLoaderCache.scala @@ -0,0 +1,25 @@ +package cbt + +import java.net._ + +object ClassLoaderCache{ + private val cache = NailgunLauncher.classLoaderCache + def get( classpath: ClassPath )(implicit logger: Logger): ClassLoader + = cache.synchronized{ + val lib = new Stage1Lib(logger) + val key = classpath.strings.sorted.mkString(":") + if( cache.containsKey(key) ){ + logger.resolver("CACHE HIT: "++key) + cache.get(key) + } else { + logger.resolver("CACHE MISS: "++key) + val cl = new cbt.URLClassLoader( classpath, ClassLoader.getSystemClassLoader ) + cache.put( key, cl ) + cl + } + } + def remove( classpath: ClassPath ) = { + val key = classpath.strings.sorted.mkString(":") + cache.remove( key ) + } +} diff --git a/stage1/MultiClassLoader.scala b/stage1/MultiClassLoader.scala new file mode 100644 index 0000000..de9bd32 --- /dev/null +++ b/stage1/MultiClassLoader.scala @@ -0,0 +1,24 @@ +/* +package cbt +import java.net._ +import scala.util.Try + +import scala.collection.immutable.Seq + + +class MultiClassLoader(parents: Seq[ClassLoader]) extends ClassLoader { + override def loadClass(name: String) = { + //System.err.println("LOADING CLASS "++name); + val c = parents.toStream.map{ + parent => + Try{ + parent.loadClass(name) + }.map(Option[Class[_]](_)).recover{ + case _:ClassNotFoundException => None + }.get + }.find(_.isDefined).flatten + c.getOrElse( ClassLoader.getSystemClassLoader.loadClass(name) ) + } + override def toString = "MultiClassLoader(" ++ parents.mkString(",") ++ ")" +} +*/ diff --git a/stage1/Stage1Lib.scala b/stage1/Stage1Lib.scala index 1ad3030..67ae049 100644 --- a/stage1/Stage1Lib.scala +++ b/stage1/Stage1Lib.scala @@ -190,6 +190,11 @@ class Stage1Lib( val logger: Logger ) extends BaseLib{ } def trapExitCode( code: => Unit ): ExitCode = { + /* + Doesn't seem to work reliably. Seems like the Security manager is not always + reset properly. Maybe some non-thread-safety issue or some Nailgun interaction. + + val old: Option[SecurityManager] = Option(System.getSecurityManager()) try{ val securityManager = new SecurityManager{ @@ -217,6 +222,9 @@ class Stage1Lib( val logger: Logger ) extends BaseLib{ } finally { System.setSecurityManager(old.getOrElse(null)) } + */ + code + ExitCode.Success } } diff --git a/stage1/URLClassLoader.scala b/stage1/URLClassLoader.scala new file mode 100644 index 0000000..870f186 --- /dev/null +++ b/stage1/URLClassLoader.scala @@ -0,0 +1,22 @@ +package cbt + +import java.net._ + +case class URLClassLoader(classPath: ClassPath, parent: ClassLoader) + extends java.net.URLClassLoader( + classPath.strings.map( + path => new URL("file:"++path) + ).toArray, + parent + ){ + override def toString = ( + scala.Console.BLUE ++ "cbt.URLClassLoader" ++ scala.Console.RESET + ++ "(\n " ++ getURLs.map(_.toString).sorted.mkString(",\n ") + ++ ( + if(getParent() != ClassLoader.getSystemClassLoader()) + ",\n" ++ getParent().toString.split("\n").map(" "++_).mkString("\n") + else "" + ) + ++ "\n)" + ) +} diff --git a/stage1/classloader.scala b/stage1/classloader.scala deleted file mode 100644 index 50e33a2..0000000 --- a/stage1/classloader.scala +++ /dev/null @@ -1,64 +0,0 @@ -package cbt -import java.io._ -import java.net._ -import java.nio.file._ -import scala.util.Try - -import scala.collection.immutable.Seq - -object ClassLoaderCache{ - private val cache = NailgunLauncher.classLoaderCache - def get( classpath: ClassPath )(implicit logger: Logger): ClassLoader - = cache.synchronized{ - val lib = new Stage1Lib(logger) - val key = classpath.strings.sorted.mkString(":") - if( cache.containsKey(key) ){ - logger.resolver("CACHE HIT: "++key) - cache.get(key) - } else { - logger.resolver("CACHE MISS: "++key) - val cl = new cbt.URLClassLoader( classpath, ClassLoader.getSystemClassLoader ) - cache.put( key, cl ) - cl - } - } - def remove( classpath: ClassPath ) = { - val key = classpath.strings.sorted.mkString(":") - cache.remove( key ) - } -} -/* -class MultiClassLoader(parents: Seq[ClassLoader]) extends ClassLoader { - override def loadClass(name: String) = { - //System.err.println("LOADING CLASS "++name); - val c = parents.toStream.map{ - parent => - Try{ - parent.loadClass(name) - }.map(Option[Class[_]](_)).recover{ - case _:ClassNotFoundException => None - }.get - }.find(_.isDefined).flatten - c.getOrElse( ClassLoader.getSystemClassLoader.loadClass(name) ) - } - override def toString = "MultiClassLoader(" ++ parents.mkString(",") ++ ")" -} -*/ -case class URLClassLoader(classPath: ClassPath, parent: ClassLoader) - extends java.net.URLClassLoader( - classPath.strings.map( - path => new URL("file:"++path) - ).toArray, - parent - ){ - override def toString = ( - scala.Console.BLUE ++ "cbt.URLClassLoader" ++ scala.Console.RESET - ++ "(\n " ++ getURLs.map(_.toString).sorted.mkString(",\n ") - ++ ( - if(getParent() != ClassLoader.getSystemClassLoader()) - ",\n" ++ getParent().toString.split("\n").map(" "++_).mkString("\n") - else "" - ) - ++ "\n)" - ) -} diff --git a/stage2/BasicBuild.scala b/stage2/BasicBuild.scala index c17bce0..bee58dd 100644 --- a/stage2/BasicBuild.scala +++ b/stage2/BasicBuild.scala @@ -15,10 +15,10 @@ import scala.util._ import ammonite.ops.{cwd => _,_} -class BasicBuild(context: Context) extends Build(context) +class BasicBuild( context: Context ) extends Build( context ) class Build(val context: Context) extends Dependency with TriggerLoop{ // library available to builds - final val logger = context.logger + implicit final val logger: Logger = context.logger override final protected val lib: Lib = new Lib(logger) // ========== general stuff ========== diff --git a/test/build/build.scala b/test/build/build.scala index 92a964b..29665a6 100644 --- a/test/build/build.scala +++ b/test/build/build.scala @@ -1,5 +1,6 @@ -import scala.collection.immutable.Seq +import cbt._ import java.io.File -class Build(context: cbt.Context) extends cbt.Build(context){ - override def dependencies = Seq( cbt.CbtDependency(context.logger) ) ++ super.dependencies +import scala.collection.immutable.Seq +class Build(context: cbt.Context) extends BasicBuild(context){ + override def dependencies = Seq( CbtDependency() ) ++ super.dependencies } -- cgit v1.2.3 From 55fff670befc97a871cf0f85c65764e108f3d3c1 Mon Sep 17 00:00:00 2001 From: Christopher Vogt Date: Fri, 11 Mar 2016 23:28:02 -0500 Subject: minor refactorings --- stage1/ClassLoaderCache.scala | 2 +- stage2/Lib.scala | 2 +- stage2/PackageBuild.scala | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'stage1') diff --git a/stage1/ClassLoaderCache.scala b/stage1/ClassLoaderCache.scala index ec343f4..18a0d0e 100644 --- a/stage1/ClassLoaderCache.scala +++ b/stage1/ClassLoaderCache.scala @@ -2,7 +2,7 @@ package cbt import java.net._ -object ClassLoaderCache{ +private[cbt] object ClassLoaderCache{ private val cache = NailgunLauncher.classLoaderCache def get( classpath: ClassPath )(implicit logger: Logger): ClassLoader = cache.synchronized{ diff --git a/stage2/Lib.scala b/stage2/Lib.scala index 7b07d06..e87a19d 100644 --- a/stage2/Lib.scala +++ b/stage2/Lib.scala @@ -192,7 +192,7 @@ final class Lib(logger: Logger) extends Stage1Lib(logger) with Scaffold{ } System.err.println(usage) taskName.foreach{ _ => - System.exit(1) + ExitCode.Failure } } } diff --git a/stage2/PackageBuild.scala b/stage2/PackageBuild.scala index b037e7f..4c4e478 100644 --- a/stage2/PackageBuild.scala +++ b/stage2/PackageBuild.scala @@ -2,7 +2,7 @@ package cbt import java.io.File import java.net.URL import scala.collection.immutable.Seq -abstract class PackageBuild(context: Context) extends Build(context) with ArtifactInfo{ +abstract class PackageBuild(context: Context) extends BasicBuild(context) with ArtifactInfo{ def `package`: Seq[File] = lib.concurrently( enableConcurrency )( Seq(() => jar, () => docJar, () => srcJar) )( _() ) -- cgit v1.2.3