Hi,
I can run my application which generates and loads code at runtime in standalone mode, but as soon as I try to use "sbt run" I get this message :
$ sbt run
[info] Loading project definition from /home/dcr/dev-new/confWithScala/project
[info] Set current project to confWithScala (in build file:/home/dcr/dev-new/confWithScala/)
[info] Running fr.janalyse.confwithscala.Main
[error] (run-main) java.lang.Error: typeConstructor inapplicable for <none>
java.lang.Error: typeConstructor inapplicable for <none>
at scala.tools.nsc.symtab.SymbolTable.abort(SymbolTable.scala:34)
at scala.tools.nsc.symtab.Symbols$Symbol.typeConstructor(Symbols.scala:880)
at scala.tools.nsc.symtab.Definitions$definitions$.scala$tools$nsc$symtab$Definitions$definitions$$booltype(Definitions.scala:157)
at scala.tools.nsc.symtab.Definitions$definitions$.init(Definitions.scala:814)
at scala.tools.nsc.Global$Run.<init>(Global.scala:697)
at fr.janalyse.confwithscala.ConfWithScala$.compiler$1(Main.scala:57)
at fr.janalyse.confwithscala.ConfWithScala$.apply(Main.scala:59)
at fr.janalyse.confwithscala.Main$.main(Main.scala:71)
at fr.janalyse.confwithscala.Main.main(Main.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
[trace] Stack trace suppressed: run last compile:run for the full output.
java.lang.RuntimeException: Nonzero exit code: 1
at scala.sys.package$.error(package.scala:27)
[trace] Stack trace suppressed: run last compile:run for the full output.
[error] (compile:run) Nonzero exit code: 1
[error] Total time: 1 s, completed 8 oct. 2012 10:01:53
SBT 0.12 is used, the build.sbt is the following :
import AssemblyKeys._
seq(assemblySettings: _*)
name := "confWithScala"
version := "0.1"
scalaVersion := "2.9.2"
mainClass in assembly := Some("fr.janalyse.confwithscala.Main")
jarName in assembly := "confwithscala.jar"
libraryDependencies += "org.scalatest" %% "scalatest" % "1.8" % "test"
libraryDependencies += "junit" % "junit" % "4.10" % "test"
libraryDependencies <++= scalaVersion { sv =>
("org.scala-lang" % "scala-compiler" % sv % "compile") ::Nil
}
Through this example application, I'm trying to use scala for configuration files instead of using properties, xml, ... For both configuration simplicity and of course scalability.
The example main code is the following :
object ConfWithScala {
class CustomConsoleReporter(settings:Settings) extends ConsoleReporter(settings) { }
def apply[T <% ConfigBase](filename: String, chosenClassName:String, baseclass:Class[T]) = {
val settings = new Settings()
settings.usejavacp.value = true
settings.deprecation.value = true
val body = io.Source.fromFile(filename)
val code =
"""class %s extends %s {
|%s
|}""".stripMargin.format(chosenClassName, baseclass.getName(), body.getLines.mkString("\n"))
val sources = List(new BatchSourceFile(filename, code))
val outdir = new VirtualDirectory("(memory)", None)
settings.outputDirs.setSingleOutput(outdir)
val global = new Global(settings, new ConsoleReporter(settings))
lazy val compiler = new global.Run()
compiler.compileSources(sources)
val loader = new AbstractFileClassLoader(outdir, getClass.getClassLoader())
val cl = loader.loadClass(chosenClassName)
cl.newInstance().asInstanceOf[T]
}
}
In fact I was wondering how I can configure SBT to make such code executable (and testable) directly from SBT, without of course any impact on the source code (I've seen in a forum some people using a dedicated configuration for their embedded compiler usage inside their code).
regards,
David.