我的团队现在可以在 OSGi 中为 Scalate 进行 Scala 编译和执行。
一般来说,ScalaCompiler 设置应该提供一组 AbstractFile 对象,这些对象对应于相关的 OSGi 包。@michid引用的 Guggla支持这一点。但是,虽然 Guggla 确实提供了 AbstractFile 层,但它还没有提供任何示例或代码来说明如何在 OSGi 环境中创建 AbstractFile 实例。执行后者的示例代码可以在 Sling 项目(Guggla 本身的起源)以及Scalate项目中找到(请参阅ScalaCompiler,但请注意我们在下面对其所做的更改)。
我们从 ServiceMix 项目中选择了 OSGi 化的 scala 包(编译器和库)。请参阅scala-compiler 包上的问题 SMX-1048(带补丁) 。
我们最初的意图是让这个在 Scalate 中工作,所以这个答案的其余部分是特定于那个项目的。
Scalate 代码已经具备在 OSGi 环境中工作所需的大部分逻辑,包括虚拟 AbstractFile 层以及设置编译器类路径。但是,我们需要修补 Scalate ( https://github.com/scalate/scalate/pull/16 ) 以使其正常工作:
1) ScalaCompiler 类的 OsgiCompiler 覆盖未正确启用,因此未将捆绑包检测为编译器的类路径输入,并且
2) 模板执行(运行时)类加载器被设置为 scalate-core 包的类加载器,导致运行时出现 CNFE。
上面的拉取请求将 OSGi 环境中的 Scalate 配置为在运行时默认为线程上下文类加载器。这似乎是获取调用者类加载器引用的最简单方法,而调用者不必显式注入它(例如,osgi:service
导出模板服务的 Spring-DM 声明可以使用该context-class-loader="service-provider"
属性自动设置它。这也使得运行Scalate OSGi 的-time 行为与已经使用 TCCL 的现有编译时行为相对应。
因此,Scalate 的调用者应该将 TCCL 设置为它自己的类加载器,或者显式地将所需的类加载器注入到模板引擎中,例如templateEngine.classLoader = ...
在执行模板之前。
2012 年 8 月 31 日更新:Scalate master 现在包含本文中提到的所有补丁。
2013 年 4 月 10 日更新:Scalate 1.6.1,通过 Scala 编译器进行运行时模板编译,与 OSGi 兼容。此外,Scala 2.10 及更高版本是已发布的有效 OSGi 捆绑包。