我已经实现了Twirl模板的动态编译,偶然发现了奇怪的问题 - scala.tools.nsc.Global
的实例一直有效,直到它使用错误的源文件失败一次。任何进一步尝试编译有效文件失败,它不会产生.class
二进制文件。我在Scala 2.11.8上。
我该如何调试和解决此问题?
以下是我创建Global
的实例的方法:
private def createScalaCompiler(compileErrors: mutable.ListBuffer[CompilationError]): Global = {
val additionalClassPathEntry: String =
List(twirlCompilerClass, this.getClass).flatMap(_.getClassLoader.asInstanceOf[URLClassLoader].getURLs.map(_.getFile)).distinct.mkString(":")
val settings = new Settings()
settings.debug.tryToSet(Nil)
settings.verbose.tryToSet(Nil)
val scalaObjectSource = Class.forName("scala.Int").getProtectionDomain.getCodeSource
if (scalaObjectSource != null) {
val compilerPath = Class.forName("scala.tools.nsc.Interpreter").getProtectionDomain.getCodeSource.getLocation
val libPath = scalaObjectSource.getLocation
val pathList = List(compilerPath, libPath)
val origBootclasspath = settings.bootclasspath.value
settings.bootclasspath.value = ((origBootclasspath :: pathList) ::: Some(additionalClassPathEntry).toList) mkString File.pathSeparator
settings.outdir.value = generatedClasses.getAbsolutePath
}
val compiler: Global = new Global(settings, new ConsoleReporter(settings) {
override def printMessage(pos: Position, msg: String): Unit = {
pos match {
case NoPosition =>
println(msg)
case _ =>
compileErrors.append(CompilationError(msg, pos.line, pos.point))
}
}
})
compiler
}
我使用如下
val compileErrors = new mutable.ListBuffer[CompilationError]
val compiler = createScalaCompiler(compileErrors)
然后compiler
的实例在功能上多次使用
def compileScalaFile(fakePath: String, content: String) {
val run = new compiler.Run
val sourceFile = new BatchSourceFile(new VirtualFile(fakePath), content)
run.compileSources(List(sourceFile))
}
如您所见,我启用了详细日志记录。有趣的是,编译有效的scala代码并不会产生任何记录输出,
在我看来,compiler
进入破碎状态。如何重置它而不从头开始重新创建(生产需要时间)?