2012-01-20 36 views
8

我在OSGi环境(Scala 2.9.1)中使用Scala模板引擎(Scalate)在运行时编译模板。由于模板是动态构建的,因此无法进行预编译。让scala编译器在OSGi运行环境中工作

为了达到这个目的,Scala编译器需要在OSGi环境中运行。但是,由于Scala编译器无法将类加载器作为输入,所以这不起作用。

从我的研究,似乎有两种通用的解决方案办法:

1)Scala的编译器插件(there is one started here,但它并没有被2009年以来感动,messages on the scala list in 2009表示,它不准备用于生产用途

2)在bundle上下文上创建一个虚拟文件系统,然后Scala编译器可以使用它。很明显,Apache的sling家伙有successfully在旧版本的Scala上使用了这种方法。

有没有人得到Scalate,Scala 2.9.1和OSGi一起工作来动态编译模板?

+1

Apache Sling的Scala脚本引擎已经转移到自己的家中https://github.com/guggla/guggla。它目前在Scala 2.9上,但它应该不会太难以与2.9.1一起工作。有关更多信息,请参阅我的会话幻灯片http://people.apache.org/~mduerig/scala4sling/和http://people.apache.org/~mduerig/scala4scripting/ – michid

+0

@michid:非常好,感谢您的链接。将进一步调查。 – Raman

回答

3

我的团队现在Scala编译和执行OSGi内的Scalate。

一般来说,ScalaCompiler设置应该提供一组对应于相关OSGi包的AbstractFile对象。这由@ michid引用的Guggla支持。但Guggla确实提供了AbstractFile层,但它尚未提供任何示例或代码来说明如何在OSGi环境中创建AbstractFile实例。可以在Sling项目(Guggla本身的起源)以及Scalate项目(请参阅ScalaCompiler,但请注意我们对其的更改)中找到执行后者的示例代码。

我们从ServiceMix项目中选择了OSGi-ified scala包(compilerlibrary)。请参阅scala编译器捆绑中的issue SMX-1048 (with patch)

我们最初的目的是为了在Scalate中得到这个工作,所以这个答案的其余部分是特定于该项目的。

Scalate代码已经拥有在OSGi环境中工作的大部分逻辑,包括虚拟AbstractFile层以及设置编译器类路径。然而,我们需要打补丁Scalate的(https://github.com/scalate/scalate/pull/16)得到它的工作:

1)ScalaCompiler类的OsgiCompiler覆盖没有被正确启用,所以捆绑的没有被检测为类路径输入到编译器和

2)模板执行(运行时)classloader被设置为scalate-core包的类加载器,导致CNFE在运行时。

上面的pull请求将OSGi环境中的Scalate配置为在运行时默认为线程上下文类加载器。这似乎是获取对调用者的类加载器的引用的最简单方法,而调用者不必明确注入它(例如,导出模板服务的Spring-DM osgi:service声明可以使用context-class-loader="service-provider"属性自动设置它,这也使得Scalate OSGi的运行时行为与已经使用TCCL的现有编译时行为相对应

因此,Scalate的调用者应该将TCCL设置为它自己的类加载器或明确地将所需的类加载器注入到模板引擎中templateEngine.classLoader = ...

更新2012年8月31日:Scalate master现在包含本帖子中提到的所有补丁。

更新2013年4月10日:通过Scala编译器进行运行时模板编译的Scalate 1.6.1与OSGi兼容。 Scala 2.10及以上版本也是发布的有效OSGi捆绑包。

0
+0

这个问题不是课堂知名度问题之一,所以我不认为这个答案是相关的。 – Raman