让 scala 编译器在 OSGi 运行时中工作

发布于 2024-12-27 18:15:29 字数 667 浏览 4 评论 0原文

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

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

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

1)一个 scala 编译器插件(有一个从这里开始,但自 2009 年以来就没有再被触及过,并且 scala 列表中的消息2009 表示尚未准备好用于生产使用

2) 在包上下文之上创建一个虚拟文件系统,然后可由 Scala 编译器使用。显然,Apache sling 的家伙成功使用了这种方法旧版本的 Scala。

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

I am using a Scala template engine (Scalate) to compile templates at runtime within an OSGi environment (Scala 2.9.1). The templates cannot be pre-compiled because they are built dynamically.

In order for this to work, the Scala compiler needs to run within the OSGi environment. However, since the Scala compiler cannot take a classloader as input, this does not work out of the box.

From my research, there appears to be two general solution approaches:

1) A scala compiler plugin (there is one started here but it has not been touched since 2009, and messages on the scala list in 2009 stated it was not ready for production use.

2) Creating a virtual file system on top of the bundle context which could then be used by the Scala compiler. Apparently the Apache sling guys have successfully used this approach on an older version of Scala.

Has anyone gotten Scalate, Scala 2.9.1, and OSGi to work together to dynamically compile templates?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

擦肩而过的背影 2025-01-03 18:15:29

我的团队现在已经在 OSGi 中为 Scalate 进行了 Scala 编译和执行。

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

我们选择了 OSGi 化的 scala 包 (编译器)服务混合项目。请参阅 scala-compiler 包上的问题 SMX-1048(带补丁)

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

Scalate 代码已经拥有在 OSGi 环境中工作所需的大部分逻辑,包括虚拟 AbstractFile 层以及设置编译器类路径。但是我们需要修补 Scalate (https://github.com/scalate/scalate/pull/16< /a>) 使其正常工作:

1) ScalaCompiler 类的 OsgiCompiler 重写未正确启用,因此未将包检测为编译器的类路径输入,以及

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

上面的拉取请求将 OSGi 环境中的 Scalate 配置为运行时默认的线程上下文类加载器。这似乎是获取调用者类加载器引用的最简单方法,而调用者无需显式注入它(例如,导出模板服务的 Spring-DM osgi:service 声明可以使用 < ,这也使得 Scalate OSGi 的运行时行为与已使用 TCCL 的现有编译时行为相对应。

code>context-class-loader="service-provider" 属性来自动设置它 呼叫者Scalate 应将 TCCL 设置为其自己的类加载器,或在执行模板之前将所需的类加载器显式注入到模板引擎,例如 templateEngine.classLoader = ...

更新 2012 年 8 月 31 日:Scalate master 现在包含。 2013 年 4 月 10 日更新:Scalate 1.6.1中提到的所有补丁

(通过 Scala 编译器进行运行时模板编译)也与 OSGi 兼容。 2.10 及更高版本是已发布的有效 OSGi 捆绑包。

My team now has Scala compilation and execution working for Scalate within OSGi.

In general, the ScalaCompiler settings should be provided with a set of AbstractFile objects that correspond to the relevant OSGi bundles. This is supported by Guggla as referenced by @michid. But while Guggla does provide the AbstractFile layer, it does not yet provide any examples or code for how to create the AbstractFile instances in an OSGi environment. Example code to do the latter can be found in the Sling project (the origin of Guggla itself) as well as in the Scalate project (see ScalaCompiler but note our changes to it below).

We chose the OSGi-ified scala bundles (compiler and library) from the ServiceMix project. See issue SMX-1048 (with patch) on the scala-compiler bundle.

Our original intent was to get this working in Scalate, and so the rest of this answer is specific to that project.

The Scalate code already had most of the logic necessary to work within an OSGi environment, including the virtual AbstractFile layer as well as setting the compiler classpath. However we needed to patch Scalate (https://github.com/scalate/scalate/pull/16) to get it working:

1) The OsgiCompiler override of the ScalaCompiler class was not being enabled properly, and so bundle's were not being detected as classpath inputs to the compiler, and

2) The template execution (run-time) classloader was being set to the classloader of the scalate-core bundle, resulting in CNFE's at runtime.

The pull request above configures Scalate in an OSGi environment to default to the thread-context classloader at runtime. That seems to be the easiest way to get a reference to the caller's classloader without the caller having to explicitly inject it (for example, a Spring-DM osgi:service declaration exporting a template service can use the context-class-loader="service-provider" attribute to set this automatically. This also makes the run-time behavior of Scalate OSGi correspond with the existing compile-time behavior which already used the TCCL.

Therefore a caller to Scalate should set the TCCL to it's own classloader or explicitly inject the desired classloader to the template engine e.g. templateEngine.classLoader = ... before executing the template.

Update 31-Aug-2012: Scalate master now contains all of the patches mentioned in this post.

Update 10-Apr-2013: Scalate 1.6.1, with runtime template compilation via the Scala compiler, is OSGi compatible. Also Scala 2.10 and above are valid OSGi bundles as released.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文