8

私は Scala テンプレート エンジン (Scalate) を使用して、OSGi 環境 (Scala 2.9.1) 内で実行時にテンプレートをコンパイルしています。テンプレートは動的に構築されるため、プリコンパイルできません。

これを機能させるには、Scala コンパイラーを OSGi 環境内で実行する必要があります。ただし、Scala コンパイラーはクラスローダーを入力として受け取ることができないため、そのままでは機能しません。

私の調査によると、2 つの一般的な解決方法があるようです。

1) scala コンパイラ プラグイン (ここで開始されたものがありますが、2009 年以降は変更されておらず、2009 年の scala リストのメッセージには、製品として使用する準備ができていないと記載されていました。

2) バンドル コンテキストの上に仮想ファイル システムを作成し、Scala コンパイラで使用できるようにします。どうやら Apache sling の連中は、古いバージョンの Scala でこのアプローチを使用して成功したようです。

テンプレートを動的にコンパイルするために、Scalate、Scala 2.9.1、および OSGi を連携させた人はいますか?

4

2 に答える 2

3

私のチームは現在、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 バンドルです。

于 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 に答える