在Scala 2.11中在运行时动态编译scala类文件
发布时间:2020-12-16 09:26:23 所属栏目:安全 来源:网络整理
导读:我有以下代码在Scala 2.10中工作,以在Scala中运行时编译外部类 /** * Compile scala files and keep them loaded in memory * @param classDir Directory storing the generated scala files * @throws IOException if there is problem reading the source
我有以下代码在Scala 2.10中工作,以在Scala中运行时编译外部类
/** * Compile scala files and keep them loaded in memory * @param classDir Directory storing the generated scala files * @throws IOException if there is problem reading the source files * @return Classloader that contains the compiled external classes */ @throws[IOException] def compileFiles(classDir: String): AbstractFileClassLoader = { val files = recursiveListFiles(new File(classDir)) .filter(_.getName.endsWith("scala")) println("Loaded files: n" + files.mkString("[",",n","]")) val settings: GenericRunnerSettings = new GenericRunnerSettings(err => println("Interpretor error: " + err)) settings.usejavacp.value = true val interpreter: IMain = new IMain(settings) files.foreach(f => { interpreter.compileSources(new BatchSourceFile(AbstractFile.getFile(f))) }) interpreter.getInterpreterClassLoader() } 然后在其他地方,我可以使用类加载器引用来实例化类,例如 val personClass = classLoader.findClass("com.example.dynacsv.PersonData") val ctor = personClass.getDeclaredConstructors()(0) val instance = ctor.newInstance("Mr","John","Doe",25: java.lang.Integer,165: java.lang.Integer,1: java.lang.Integer) println("Instantiated class: " + instance.getClass.getCanonicalName) println(instance.toString) 但是,由于已从scala.tools.nsc.interpreter.IMain中删除了getInterpreterClassLoader方法,因此上述操作不再有效.此外,AbstractFileClassLoader已被移动和弃用.不再允许从外部包调用类加载器中的findClass方法. 在Scala 2.11中执行上述操作的推荐方法是什么?谢谢! 解决方法
如果你的目标是在运行时运行外部scala类,我建议使用eval和scala.tools.reflect.ToolBox(它包含在REPL中,但是对于正常使用,你必须添加scala-reflect.jar):
import scala.reflect.runtime.universe import scala.tools.reflect.ToolBox val tb = universe.runtimeMirror(getClass.getClassLoader).mkToolBox() tb.eval(tb.parse("""println("hello!")""")) 您还可以使用tb.compile编译文件. 用示例修改:假设您有外部文件 class PersonData() { val field = 42 } scala.reflect.classTag[PersonData].runtimeClass 所以你也是 val clazz = tb.compile(tb.parse(src))().asInstanceOf[Class[_]] val ctor = clazz.getDeclaredConstructors()(0) val instance = ctor.newInstance() 其他可能性(几乎)是无限的,您可以获得完整的树AST并根据需要使用它: showRaw(tb.parse(src)) // this is AST of external file sources // this is quasiquote val q""" class $name { ..$stats } scala.reflect.classTag[PersonData].runtimeClass """ = tb.parse(src) // name: reflect.runtime.universe.TypeName = PersonData // stats: List[reflect.runtime.universe.Tree] = List(val field = 42) println(name) // PersonData 有关这些技巧,请参阅官方文档: http://docs.scala-lang.org/overviews/reflection/symbols-trees-types.html http://docs.scala-lang.org/overviews/quasiquotes/intro.html (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
推荐文章
站长推荐
- Angular 2:如何在该Component中访问自定义Compo
- 实战WebService II: SOAP篇(基于php)
- Kubernetes-kubectl exec bash-会话拖放和行宽
- bash – 如何将重定向符号分配给变量以组装命令行
- 免费的响应式Bootstrap模板 - Codester
- scala – 什么是模式匹配序列理解的惯用方式?
- 推荐13款优秀的Twitter Bootstrap JavaScript插件
- Angular2 Dependency Injection
- runtime modeler error: Wrapper class org.exam
- Scala中的正确关联方法有什么好处?
热点阅读