私のチームは現在、OSGi 内の Scalate で動作する Scala のコンパイルと実行を行っています。
一般に、ScalaCompiler 設定には、関連する OSGi バンドルに対応する一連の AbstractFile オブジェクトを指定する必要があります。これは、@michid で参照されている Guggla によってサポートされています。しかし、Guggla は AbstractFile レイヤーを提供していますが、OSGi 環境で AbstractFile インスタンスを作成する方法の例やコードはまだ提供していません。後者を行うためのサンプル コードは、Sling プロジェクト (Guggla 自体の起源) とScalateプロジェクト ( ScalaCompilerを参照してください。ただし、以下の変更に注意してください) で見つけることができます。
ServiceMix プロジェクトからOSGi 化された scala バンドル (コンパイラーとライブラリー) を選択しました。scala-compiler バンドルの問題 SMX-1048 (パッチ付き)を参照してください。
私たちの当初の意図は、これを Scalate で機能させることだったので、この回答の残りの部分はそのプロジェクトに固有のものです。
Scalate コードには、仮想 AbstractFile レイヤーやコンパイラ クラスパスの設定など、OSGi 環境内で動作するために必要なロジックのほとんどが既に含まれています。ただし、機能させるには、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 の動作は、すでに TCCL を使用していた既存のコンパイル時の動作に対応しています。
したがって、Scalate の呼び出し元は、TCCL を独自のクラスローダーに設定するか、テンプレートをtemplateEngine.classLoader = ...
実行する前などに、目的のクラスローダーをテンプレート エンジンに明示的に挿入する必要があります。
2012 年 8 月 31 日更新: Scalate マスターには、この投稿で言及されているすべてのパッチが含まれるようになりました。
2013 年 4 月 10 日更新: Scalate 1.6.1 は、Scala コンパイラーによるランタイム テンプレート コンパイルを使用して、OSGi と互換性があります。また、Scala 2.10 以降は、リリースされた時点で有効な OSGi バンドルです。