8

我正在使用 Scala 模板引擎 (Scalate) 在 OSGi 环境 (Scala 2.9.1) 中运行时编译模板。模板无法预编译,因为它们是动态构建的。

为了使其工作,Scala 编译器需要在 OSGi 环境中运行。但是,由于 Scala 编译器不能将类加载器作为输入,所以这不是开箱即用的。

根据我的研究,似乎有两种通用的解决方法:

1)一个 scala 编译器插件(这里有一个,但自 2009 年以来就没有被触及过,2009 年scala 列表上的消息表明它还没有准备好用于生产使用。

2) 在捆绑上下文之上创建一个虚拟文件系统,然后可以由 Scala 编译器使用。显然,Apache sling 人员已经在旧版本的 Scala 上成功地使用了这种方法。

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

4

2 回答 2

3

我的团队现在可以在 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 捆绑包。

于 2012-01-28T20:23:42.873 回答
0

我认为您需要设置好友政策。以下应该会有所帮助。

http://wiki.eclipse.org/index.php/Context_Class_Loader_Enhancements#Buddy_Policy

http://www.eclipsezone.com/eclipse/forums/t90282.html

http://help.eclipse.org/indigo/topic/org.eclipse.platform.doc.isv/reference/misc/bundle_manifest.html

在您的包中,您可以说您需要使用与另一个包相同的类加载器。

于 2012-01-21T15:04:25.427 回答