diff options
author | Jan Christopher Vogt <oss.nsp@cvogt.org> | 2016-11-03 14:30:33 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-11-03 14:30:33 -0400 |
commit | 775a9582942e64bf492687194e016f2034a81feb (patch) | |
tree | 92ac88a45f77f033dd58a003df942fa3aa67362a | |
parent | 131954279c0937b499bddc52c15a300b1af7b9bc (diff) | |
parent | eb21b485fbc3972f66bed7d8af62900712cb3b0b (diff) | |
download | cbt-775a9582942e64bf492687194e016f2034a81feb.tar.gz cbt-775a9582942e64bf492687194e016f2034a81feb.tar.bz2 cbt-775a9582942e64bf492687194e016f2034a81feb.zip |
Merge pull request #293 from cvogt/resources
Add support for resources (still limited by CBT's classloader visibil…
-rw-r--r-- | examples/resources-example/build/build.scala | 21 | ||||
-rw-r--r-- | examples/resources-example/build/build/build.scala | 20 | ||||
-rw-r--r-- | examples/resources-example/my-resources/foo.text | 1 | ||||
-rw-r--r-- | examples/resources-example/resources/foo.text | 1 | ||||
-rw-r--r-- | examples/resources-example/src/Main.scala | 27 | ||||
-rw-r--r-- | nailgun_launcher/MultiClassLoader2.java | 17 | ||||
-rw-r--r-- | stage1/MultiClassLoader.scala | 14 | ||||
-rw-r--r-- | stage2/BasicBuild.scala | 6 |
8 files changed, 106 insertions, 1 deletions
diff --git a/examples/resources-example/build/build.scala b/examples/resources-example/build/build.scala new file mode 100644 index 0000000..aec5d79 --- /dev/null +++ b/examples/resources-example/build/build.scala @@ -0,0 +1,21 @@ +import cbt._ +class Build(val context: Context) extends BaseBuild{ + /* + override def dependencies = + super.dependencies ++ // don't forget super.dependencies here + Seq( + // source dependency + DirectoryDependency( projectDirectory ++ "/subProject" ) + ) ++ + Resolver( mavenCentral ).bind( + // CBT-style Scala dependencies + ScalaDependency( "com.lihaoyi", "ammonite-ops", "0.5.5" ) + MavenDependency( "com.lihaoyi", "ammonite-ops_2.11", "0.5.5" ) + + // SBT-style dependencies + "com.lihaoyi" %% "ammonite-ops" % "0.5.5" + "com.lihaoyi" % "ammonite-ops_2.11" % "0.5.5" + ) + */ + override def resourceClasspath = super.resourceClasspath ++ ClassPath(Seq(projectDirectory ++ "/my-resources")) +} diff --git a/examples/resources-example/build/build/build.scala b/examples/resources-example/build/build/build.scala new file mode 100644 index 0000000..f700060 --- /dev/null +++ b/examples/resources-example/build/build/build.scala @@ -0,0 +1,20 @@ +import cbt._ +class Build(val context: Context) extends BuildBuild{ + /* + override def dependencies = + super.dependencies ++ // don't forget super.dependencies here + Seq( + // source dependency + DirectoryDependency( projectDirectory ++ "/subProject" ) + ) ++ + Resolver( mavenCentral ).bind( + // CBT-style Scala dependencies + ScalaDependency( "com.lihaoyi", "ammonite-ops", "0.5.5" ) + MavenDependency( "com.lihaoyi", "ammonite-ops_2.11", "0.5.5" ) + + // SBT-style dependencies + "com.lihaoyi" %% "ammonite-ops" % "0.5.5" + "com.lihaoyi" % "ammonite-ops_2.11" % "0.5.5" + ) + */ +} diff --git a/examples/resources-example/my-resources/foo.text b/examples/resources-example/my-resources/foo.text new file mode 100644 index 0000000..f82e417 --- /dev/null +++ b/examples/resources-example/my-resources/foo.text @@ -0,0 +1 @@ +Hello from a resource in my-resources/ (the additional location manually added here in build.scala) diff --git a/examples/resources-example/resources/foo.text b/examples/resources-example/resources/foo.text new file mode 100644 index 0000000..6d7c85a --- /dev/null +++ b/examples/resources-example/resources/foo.text @@ -0,0 +1 @@ +Hello from a resource in resources/ (the default location) diff --git a/examples/resources-example/src/Main.scala b/examples/resources-example/src/Main.scala new file mode 100644 index 0000000..3bc0943 --- /dev/null +++ b/examples/resources-example/src/Main.scala @@ -0,0 +1,27 @@ +import java.nio.file.{Files, Paths} +object Main extends App { + // Be aware that CBT currently isolates classloaders of dependencies + // your dependencies will not see the resources of your project + // This means that e.g. spray will not see a application.conf in your project's + // resources/ directory. See https://github.com/cvogt/cbt/issues/176 + println( + "foo.text in resources contains: " ++ + new String( + Files.readAllBytes( + Paths.get( getClass.getClassLoader.getResource("foo.text").getFile ) + ) + ) + ) + import scala.collection.JavaConverters._ + println( + "foo.text in resources and my-resources:\n" ++ + getClass.getClassLoader.getResources("foo.text").asScala.map( + resource => + new String( + Files.readAllBytes( + Paths.get( resource.getFile ) + ) + ) + ).mkString + ) +} diff --git a/nailgun_launcher/MultiClassLoader2.java b/nailgun_launcher/MultiClassLoader2.java index fadd963..46e7527 100644 --- a/nailgun_launcher/MultiClassLoader2.java +++ b/nailgun_launcher/MultiClassLoader2.java @@ -1,5 +1,6 @@ package cbt; import java.net.*; +import java.io.*; import java.util.*; public class MultiClassLoader2 extends ClassLoader{ @@ -23,6 +24,22 @@ public class MultiClassLoader2 extends ClassLoader{ // System.err.println("NOT FOUND: "+name); return null; } + public URL findResource(String name){ + for(ClassLoader parent: parents){ + URL res = parent.getResource(name); + if(res != null) return res; + } + return null; + } + public Enumeration<URL> findResources(String name) throws IOException{ + ArrayList<URL> resources = new ArrayList<URL>(); + for(ClassLoader parent: parents){ + for(URL resource: Collections.list(parent.getResources(name))){ + resources.add( resource ); + } + } + return Collections.enumeration(resources); + } public String toString(){ return super.toString() + "(" + Arrays.toString(parents) +")"; } diff --git a/stage1/MultiClassLoader.scala b/stage1/MultiClassLoader.scala index 416e0cd..9546d47 100644 --- a/stage1/MultiClassLoader.scala +++ b/stage1/MultiClassLoader.scala @@ -1,5 +1,6 @@ package cbt import java.net._ +import scala.collection.JavaConverters._ // do not make this a case class, required object identity equality class MultiClassLoader(final val parents: Seq[ClassLoader])(implicit val logger: Logger) extends ClassLoader(null) with CachingClassLoader{ @@ -14,6 +15,19 @@ class MultiClassLoader(final val parents: Seq[ClassLoader])(implicit val logger: _.loadClass(name) ).getOrElse( null ) } + + // FIXME: is there more than findClass and findResource that needs to be dispatched? + override def findResource(name: String): URL = { + parents.foldLeft(null: URL)( + (acc, parent) => if( acc == null ) parent.getResource(name) else null + ) + } + override def findResources(name: String): java.util.Enumeration[URL] = { + java.util.Collections.enumeration( + parents.flatMap( _.getResources(name).asScala ).asJava + ) + } + override def toString = ( scala.Console.BLUE ++ super.toString diff --git a/stage2/BasicBuild.scala b/stage2/BasicBuild.scala index 8c65f3f..128d2f8 100644 --- a/stage2/BasicBuild.scala +++ b/stage2/BasicBuild.scala @@ -101,7 +101,11 @@ trait BaseBuild extends BuildInterface with DependencyImplementation with Trigge final def compileClasspath : ClassPath = dependencyClasspath ++ ClassPath( compileDependencies.flatMap(_.exportedClasspath.files).distinct ) - def exportedClasspath : ClassPath = ClassPath(compile.toSeq) + def resourceClasspath: ClassPath = { + val resourcesDirectory = projectDirectory ++ "/resources" + ClassPath( if(resourcesDirectory.exists) Seq(resourcesDirectory) else Nil ) + } + def exportedClasspath : ClassPath = ClassPath(compile.toSeq) ++ resourceClasspath def targetClasspath = ClassPath(Seq(compileTarget)) // ========== compile, run, test ========== |