Hallo Leute,
ich wollte nur rasch kundtun, dass ich gerade einige Anstrengungen auf mich nehme, die absolut angenehme und wirklich hervorragend erweiterbare OSGI Service Platform von Java nach PHP migriere.
Wer es nicht kennt: OSGi ist ein Framework für komponentenbasierte, Service orientierte Entwicklung von Anwendungen. Der Fokus liegt dabei auf Kapselung aller Ressourcen einer Komponente, Hot Deployment und der Installation und dem Betrieb verschiedener Versionen einer Komponenten gleichzeitig.
PHP bietet sich dafür meines Erachtens und nach der Evaluierung einer prototypischen Case study an. Einige Konzepte wie bsp. Hot Deployment sind natürlich nur bedingt umsetzbar. Darüber hinaus baut OSGi verstärkt auf CustomClassLoading und dem Package-Prinzip, beides in PHP bekanntlich nur rudimentär vorhanden (abgesehen von den an sich als rudimentär zu bezeichnenden OO-Fähigkeiten von PHP).
Nichtsdestotrotz ist bereits der Mechanismus des expliziten Im-/Exports einzelner Ressourcen eines Bundle realisiert. Sprich, ein "gefaktes" Classloading unter Berücksichtung der Bundle spezifischen Manifest-Dateien klappt bereits im Sinne der OSGi-Kapselung.
Als nächstes kommen die Services an die Reihe.
In meiner Vorstellung lassen sich auf schnellste Art und Weise Erweiterungen bzw. neue Komponenten in eine Webapplication istallieren, die sämtliche Abhängigkeiten entweder selbst auflösen oder sich dazu für die Services eines bereits bestehenden Bundle bedienen.
Wen dieser Beitrag neugierig gemacht hat, der sei aufgefordert hier zu posten.
Bis dann
Timothy
Ankündigung
Einklappen
Keine Ankündigung bisher.
OSGi Service Platform für PHP
Einklappen
Neue Werbung 2019
Einklappen
X
-
OSGi Service Platform für PHP
Stichworte: -
-
Hallo Leute,
hat ein wenig gedauert, nun meine Erfahrungen bzgl. des dynamischen Einladens der Klassenbeschreibungen.
Die Variante von Dr.E. hat nihct ganz so funktioniert, wie ich es erhofft hatte, dies hat mit der von mir propagierten ClassLoader-Architektur zu tun. Ich verwende einen eigens implementierten ClassLoader, der die Abhängigkeiten von Bundles prüft und auflöst, ggf. eine Exception wirft, wenn die Export-und Import-Header das Verwenden einer Klasse nicht zulassen. Dazu verwendet der ClassLoader das Framework-Objekt (das zentrale Objekt, in dem die BundleRegistry, etc. vorgehalten werden). Leider steht zur Zeit des Wakeup dieses Objekt nocht nicht zur Verfügung und wenn während des Wakeups Klassen eingeladen werden, die Klassen aus anderen Bundles per ClassLoader einladen (bei Services bspw. das Interface des Services), dann kann der ClassLoader seine Arbeit nicht vollrichten, da das Framework-Objekt noch nicht vollständig wiederhergestellt ist.
Ich hatte 2 Möglichkeiten zur Wahl. Erstere bedeutete Verzicht auf den ClassLoader (abgelehnt). Zweitere verwendet eine externe Textdatei um alle bisher eingeladenen Service-Klassen mit absolutem Pfad zu speichern. Wenn die Framework-Klasse initialisiert wird, gibt es eine Art Static-Konstruktor (wie in Java), der ausgeführt wird, wenn die Klasse geladen wird (nicht wenn das Objekt instanziiert wird). Dann wird der ClassLoader angestoßen, der nunmehr nicht auf das Framework-Objekt zugreift, sondern auf die Textdatei. Einziger Wermutstropfen: Das 'require_once'-Statement für die Framework-Klasse muss vor dem Start der Session erfolgen. Abgesehen von dieser Einschränkung läuft das ganze jetzt sehr rund und angenehm. Der nächste Schritt wird der ServiceTracker sein.
Timothy<
-
Hey Dr.E.,
das ist natürlich eine andere mögliche Variante. Die ServiceRegistry schreibt die aktuell vorgehaltenen Klassenpfade in eine Datei und liest diese beim Deserialisieren der Klasse ServiceRegistry wieder aus. Das ist eine 3. Möglichkeit, die mir persönlich sogar am elegantesten erscheint.
Die ServiceRegistry bedarf dabei keiner großen Anpassungen, da der BundleContext beim Registrieren natürlich über sämtliche Informationen des aktuellen Bundles (das den Service registriert) verfügt.
Tolle Variante, probiere ich heute Abend aus und poste meine Ergebnisse.
Danke dir.
Timothy
Einen Kommentar schreiben:
-
Hallo Timothy,
ich würde eine Änderung beim Registrieren des Services einführen. Möchte sich ein Service registrieren, muss er dir (=ServiceRegistry) alle Bundle-Informationen samt Klassen mitteilen. Ist prinzipiell Overhead, schafft dir aber Probleme vom Hals. Damit hast du beim wakeup die Möglichkeit, dir die entsprechenden Bundles (~Klassen) zu laden und danach die Objekte zu deserialisieren.
Einen Kommentar schreiben:
-
Hallöchen,
heute geht es ja in großen Schritten voran Ich würde trotzdem gerne Eure Meinung zu einer wirklichen Hürde hören:
Ich bin gerade dabei die Services zu ermöglichen. Diese werden - wie sollte es sein - in einer ServiceRegistry abgelegt, welche zusammen mit dem "Framework" in einer Session-Variable persistiert wird. Dadurch sind einmal registrierte Services über die Aufrufe hinweg in der "Runtime" vorgehalten. Prinzipiell klappen die Services und die ServiceFactory schon im Sinne der OSGi. ABER:
Die Klassendefinitionen eines Services, der von einem Bundle registriert wird, wird erst innerhalb der Ausführung des Codes des Bundles eingeladen. Wenn jetzt versucht wird, die ServiceRegsitry zu deserialisieren, befinden sich Objekte dort, deren Klassendefinition noch nicht geladen wurde!!!
Würde allerdings bereits vor der eigentlichen Deserialisierung der Klassenimport stattfinden, koppelt man damit das Framework mit allen Services exportierenden Bundles -> no go!
Lösungen: Ich habe folgende verschiedenen Workaround, zu denen ich gerne eure Meinung hörte.
1. Verzicht auf die Persistenz der ServiceRegistry und eine erneute Registrierung aller Services bei jedem Aufruf. Das würde leider auch eine etwaige lazy-Activation Policy zunichte machen, da der Service ja jedes mal wieder gelöscht wird am Ende des Skripts. Folglich sollten Services nur in der Activator->start()-Methode registriert werden.
2. Jedes Skript definiert ein kleines PHP-Skript, welches in einem Hashtable sämtliche qualifizierten Klassennamen und -pfade aufzählt, welche direkt oder indirekt exportiert werden. In der wakeup()-Methode des Frameworks werden von allen vorhandenen Bundles diese Skripte gelesen (sofern vorhanden) und die jeweiligen Klassendefinitionen geladen. dann bliebe das "reine" Service-Prinzip vorhanden, mit dem unschönen Overhead, dass alle Klassen "auf Anhieb" geladen werden.
3. Ist mir während des Schreibens entfallen Verdammt!
+++++
Das Framework läuft eigentlich ganz schön, viele Punkte aus der Spezifikation sind machbar. Nun funktionieren bei den Import- und ExportPackages die Versionsspannen und die Include/Exclude-Anweisungen. PHP zickt immer dann herum, wenn es um die VM geht...
Bin auf Eure Meinungen oder vielleicht andertweitige Ideen sehr gespannt.
Timothy
Einen Kommentar schreiben:
-
Grüße Euch Gott,
ja, es ist in der Tat eine ziemlich nerviger Nebeneffekt sich stets einen neuen Namespace, bestehend aus Version und Bundle-SymbolicName, zu basteln. Ich werde mich damit demnächst mal auseinander setzen und schauen, ob der Namespace auch aus propertie-Dateien ausgelesen werden kann. Ohne es getestet zu haben erweist es sich zumindest als positiv, dass die Metadaten zu einem Bundle ausgelesen und verarbeitet werden, ehe der erste Zugriff auf den Activator oder irgend eine andere Klasse des Bundles erfolgt. Das KÖNNTE klappen
Ich werde die Umstellung auf Namespaces und PHP 5.3 voraussichtlich für einen zweiten Iterationszyklus anleiern. Erstmal müssen einige Grundkonzepte stehen; momentan sind es die ServiceTracker und die Web-spezifischen Erweiterungen, die ein wenig an das Konzept von Extension Points angelehnt sind. Mal schauen.
Danke auf jeden Fall für euer Feedback.
Gruß
Timothy
Einen Kommentar schreiben:
-
Ich meine, die Tage erst gelesen zu haben, dass zwar der Namespace-Support an sich soweit einigermaßen stabil ist, allerdings die entgültige Syntax immernoch nicht 100%ig feststeht. Leider finde ich die Quelle nicht mehr - vlt. werfe ich das aber gerade auch nur irgendwie durcheinander.
Fest steht, dass jedes PlugIn bzw. jede PlugIn-Version seinen eigens benannten Namespace nutzen muss, d.h. der Namespacename trägt die Versionsnr. - oder irre ich mich? Das könnte ein lästiges Hindernis in der Entwicklung von PlugIns werden. An der Stelle wäre zu evaluieren, wie dynamisch mit den Namespaces umgegangen werden kann.
Würde mich freuen, wenn du hier vlt. die ein oder anderen Erkenntnisse veröffentlichen würdest. Leider fehlt mir im Moment die Zeit, mich selbst mit der 5.3er PHP-Version zu beschäftigen.
Einen Kommentar schreiben:
-
Hallo Timothy,
Wie sehen Eure Meinungen dazu aus?
Einen Kommentar schreiben:
-
Hallo Leute,
ich habe mich gerade dazu entschieden, das OSGi-Derivat ausschließlich für PHP 5.3 zu entwickeln. Es haben sich bei der Implementierung der OSGi Services einige Probleme ergeben. Es ist bekanntlich möglich Bundles in verschiedenen Versionen zu deployen. Ich habe ein kleines Szenario aufgebaut, indem zwei Bundles bundle_1.0.0 und bundle_1.1.0 jeweils das Interface IFoo exportieren.
Zwei andere Bundles importieren die Interfaces (oder besser die Packages der Interfaces) und implementieren diese einmal in der Version 1.0.0 und einmal in der Version 1.1.0.
Da die Interfaces aber den gleichen Namen besitzen, erhalte einen 'Cannot redeclare...' error. Der gleiche Fehler hat mich schon zu einem hässlichen Hack bzgl. der Bundle-Activator-Klassen gezwungen. Es ist halt definitiv nicht möglich zwei gleichnamige aber logisch unterschiedliche Klassen in PHP zu definieren und zu verwenden.
Mit PHP 5.3 erhoffe ich mir Klarheit durch die Namespaces. Vermutlich wird dass dann ein zusätzlicher Header in der Manifest-Datei. Mal sehen.
Wie sehen Eure Meinungen dazu aus?
So long
Timothy
Einen Kommentar schreiben:
-
Ein sehr interessanter (und lobenswerter) Ansatz!
Für die Umsetzung wäre der Einsatz von PHP 5.3 mit Sicherheit interessant, vorallem wg. der Namespaces. Auf diese Art und Weise könnte man Klassen gleichen Namens (verschiedene Versionen z.B.) in unterschiedliche Namespaces verfrachten und so parallel nutzen - soweit die Theorie.
Vor paar Tagen ist die erste Alpha Version von PHP 5.3 erschienen. Als Releasetermin ist das dritte oder vierte Quartal genannt.
Einen Kommentar schreiben:
-
Hi Leute,
gestern ist der emulierte OSGi-Cache bzw. die Runtime fertig geworden. Hätte mich ein hässlicher SimpleXMLElement Serialisierungfehler nicht über Stunden blockiert, wäre ich schon viel weiter
Ich habe mich dazu entschlossen die OSGi-Manifest-Datei nur in XML-Form bereit zu stellen. Die proprietäre Manifest-Datei, wie sie derzeit noch in der OSGi-Spec beschrieben wird, ist sicherlich nur historisch gewachsen. Man erkennt dies, da neuere deklarative Informationen (wie beispielseweise die Declarative Services) ja auch nur in XML bereit gestellt werden. Sicherlich wird dies über kurz oder lang auch eine Alternative für die Manifest-Datei werden.
Gestern habe ich mich dazu entschieden, das Framework selbst ebenfalls als Bundle zu deployen. Das ist einfach sauberer; der erste Ansatz war, das Framework als "plain-code" einzubinden. Jetzt besitzt es die gleiche Struktur wie jedes andere Bundle und besitzt eigene Meta-Informationen.
So, ein kurzer Zwischenstand.
Timothy
Einen Kommentar schreiben:
-
Hallo Timothy,
Derzeit überlege ich, ob ich noch rasch auf PHAR umbaue, vielleicht auch auf phk. Hat jemand Erfahrungsberichte in diesem Bereich? Packages wären ein ziemlicher Fortschritt für dieses Projekt, nur bin ich mir noch nicht sicher, ob ich die jetzt sofort unterstützen soll, oder erst mit PHP 5.3 ein größeres Update bringen soll?!
Einen Kommentar schreiben:
-
Hallo Leute,
eine Projektseite gibt es nicht. Ich werde eine anlegen, wenn ich die erste lauffähige Version vorweisen kann.
Technische Details? PHP ab 5.2. Das war es eigentlich. Datenbanken sind erstmal nicht vonnöten, da jedes Bundle bekanntermaßen sämtliche Meta-Informationen selbst mitbringt.
Das Persistieren der verschiedenen Registrys übernimmt ein SessionManager, der den PHP-internen Session-Mechanismus kapselt.
Prinzipiell sei gesagt, dass sämtliche Funktionen, die ich emuliere, bspw. die Bundle-Dependencys oder die gefakte Runtime, natürlich mit den PHP-Mitteln auszuhebeln sind. Gegen Fahrlässigkeit ist sicherlich keiner gefeit.
Nähe zu OSGi ist auf jeden Fall vorhanden, wenngleich es keine 1:1-Umsetzung der OSGi-Spec wird. Ich betrachte daher das System eher als OSGi inspiriert.
Derzeit überlege ich, ob ich noch rasch auf PHAR umbaue, vielleicht auch auf phk. Hat jemand Erfahrungsberichte in diesem Bereich? Packages wären ein ziemlicher Fortschritt für dieses Projekt, nur bin ich mir noch nicht sicher, ob ich die jetzt sofort unterstützen soll, oder erst mit PHP 5.3 ein größeres Update bringen soll?! Wenn ich bis zu dessen Release überhaupt was vorzeigbares habe.
Momentan steht neben 80h HiWi-Arbeit noch die Masterarbeit und die Geburt meines ersten Kindes an. KLingt nach anstrengenden Monaten bis März
Das sind, denke ich, auf den ersten Schlag genug Informationen. Mehr weiß ich selber noch nicht.
so long
Timothy
Einen Kommentar schreiben:
-
Hallo,
ich werde es auch beobachten ... wird bestimmt spannend.
Gruß,
Jumper, the II.
Einen Kommentar schreiben:
Einen Kommentar schreiben: