Have an application split into sub projects in my Build.scala.
I need to run a Task on Compile against a set of sub project classes; since I have no way to statically import sub project classes without making the sub projects themselves into plugins and depending on them, I'm resorting to reflection.
val fooTask = TaskKey[Unit]("foo", "Description...")
val foo = fooTask := {
val classpath = Array("pathA", "pathB", "...")
val sbtLoader = this.getClass.getClassLoader
val appLoader: ClassLoader = URLClassLoader(classpath, sbtLoader)
val mainClass = appLoader.loadClass("Foo")
val mainMethod = mainClass.getMethod("main", classOf[Array[String]])
try {
mainMethod.invoke(new Object, Array(""))
}
catch {
case e: InvocationTargetException => println(e.getCause)
}
}
Everything works fine if no reflection is involved in the invoked method, but unfortunately I need reflection there as well! FWIW, Foo's use case is to generate, and write to static file at compile time, a set of Play framework javascript routes based on each sub project's controllers:
collection.map{ clazz=>
clazz.getFields.map(_.get(null)).flatMap { c=>
c.getClass.getDeclaredMethods.map(
_.invoke(c).asInstanceOf[JavascriptReverseRoute]
)
}
}.flatten
It blows up with java.lang.ClassNotFoundException: scala.reflect.ClassTag$ which only exists in Scala 2.10, fine for the application which is compiled against 2.10.2. SBT 0.12.3, however, uses Scala 2.9.2 and that must be where the reflection house of cards comes crashing down.
Via terminal session I can run desired class directly via Scala 2.10.2 and the javascript routes are generated just fine. I'd prefer not to have the Task fire up a new Scala session on each compile, however.
Anyone have ideas for workarounds? Totally stuck, SBT 0.13 is too new to try to build Play and all its 0.12 based plugins.
Thanks