Mein Team hat jetzt die Scala-Kompilierung und -Ausführung für Scalate in OSGi.
Im Allgemeinen sollten die ScalaCompiler-Einstellungen mit einer Reihe von AbstractFile-Objekten versehen sein, die den relevanten OSGi-Bundles entsprechen. Dies wird von Guggla unterstützt, auf die von @michid verwiesen wird. Während Guggla die AbstractFile-Schicht bereitstellt, enthält sie noch keine Beispiele oder Code zum Erstellen der AbstractFile-Instanzen in einer OSGi-Umgebung. Beispielcode, um letzteres zu tun, kann im Projekt Sling (der Ursprung von Guggla selbst) sowie im Projekt Scalate ( siehe ScalaCompiler aber notieren Sie unsere Änderungen unten).
Wir haben die OSGi-ified scala bundles gewählt ( Compiler und Bibliothek ) aus dem ServiceMix-Projekt. Siehe SMX-1048 (mit Patch) im Scala-Compiler-Paket.
Unsere ursprüngliche Absicht war es, dass dies in Scalate funktionierte, und daher ist der Rest dieser Antwort spezifisch für dieses Projekt.
Der Scalate-Code verfügte bereits über den Großteil der erforderlichen Logik, um in einer OSGi-Umgebung zu arbeiten, einschließlich der virtuellen AbstractFile-Ebene sowie des Compiler-Klassenpfads. Allerdings mussten wir Scalate ( Ссылка ) patchen, damit es funktioniert:
1) Die OsgiCompiler-Überschreibung der ScalaCompiler-Klasse wurde nicht richtig aktiviert, und daher wurden Bundles nicht als Classpath-Eingaben für den Compiler erkannt und
2) Der Classloader für die Template-Ausführung (Runtime) wurde auf den Classloader des Scale-Core-Bundles gesetzt, was zur Laufzeit zu CNFE führt.
Die obige Pull-Anforderung konfiguriert Scalate in einer OSGi-Umgebung standardmäßig so, dass der Thread-Context-Classloader zur Laufzeit verwendet wird. Das scheint der einfachste Weg zu sein, einen Verweis auf den Classloader des Aufrufers zu erhalten, ohne dass der Aufrufer ihn explizit einfügen muss (z. B. kann eine Spring-DM %code% -Deklaration, die einen Template-Service exportiert, das Attribut %code% verwenden, um dies automatisch festzulegen Dies führt dazu, dass das Laufzeitverhalten von Scalate OSGi mit dem vorhandenen Kompilierungsverhalten übereinstimmt, das bereits die TCCL verwendet hat.
Daher sollte ein Aufrufer für Scalate die TCCL auf ihren eigenen Klassenlader setzen oder den gewünschten Klassenlader explizit in die Vorlagenmaschine einspeisen, z. %code% vor dem Ausführen der Vorlage.
Update 31-Aug-2012: Scalate-Master enthält jetzt alle in diesem Post erwähnten Patches.
Update 10-Apr-2013: Scalate 1.6.1, mit Laufzeittabelle Kompilierung über den Scala-Compiler, ist OSGi-kompatibel. Auch Scala 2.10 und höher sind gültige OSGi-Bundles als freigegeben.
Ich denke, Sie müssen die Buddy-Richtlinie festlegen. Folgendes sollte helfen.
In Ihrem Paket können Sie sagen, dass Sie denselben Klassenlader wie ein anderes Paket verwenden müssen.
Ich verwende eine Scala-Vorlagen-Engine (Scalate), um Vorlagen zur Laufzeit in einer OSGi-Umgebung (Scala 2.9.1) zu kompilieren. Die Vorlagen können nicht vorkompiliert werden, da sie dynamisch erstellt werden.
Damit dies funktioniert, muss der Scala-Compiler in der OSGi-Umgebung ausgeführt werden. Da der Scala-Compiler jedoch keinen Classloader als Eingabe verwenden kann, funktioniert das nicht sofort.
Aus meiner Forschung scheint es zwei allgemeine Lösungsansätze zu geben:
1) Ein Scala-Compiler-Plugin ( hier wurde eines gestartet , aber seit 2009 nicht mehr berührt, und Nachrichten auf der Scalaliste im Jahr 2009 gaben an, dass sie nicht für den Produktionseinsatz bereit waren.
2) Erstellen eines virtuellen Dateisystems über dem Bundle-Kontext, das dann vom Scala-Compiler verwendet werden kann. Anscheinend haben die Apache-Sling-Leute diesen Ansatz erfolgreich auf einer älteren Version von Scala angewendet .
Hat jemand Scalate, Scala 2.9.1 und OSGi dazu gebracht, zusammen zu arbeiten, um Vorlagen dynamisch zu kompilieren?