PHP-Anwendungen mit Java-Backends verbinden
Seit sich Unternehmensprozesse immer mehr ins Web verlagern, wächst das Bedürfnis, etablierte Internet-Techniken wie PHP mit Java-Enterprise-Anwendungen zu kombinieren. Standardprodukte für die Verknüpfung sind zwar noch Mangelware, einige Ansätze jedoch vielversprechend.

Wer sein Java-Backend mit dynamischen Webseiten, oft erstellt mit dem populären PHP, verbinden will, kann sich noch nicht aus einer reichen Auswahl an geeigneter Technik oder gar bei zahlreichen ausgereiften Produkten bedienen. Trotzdem lohnt es sich, einiges von dem Vorhandenen näher zu untersuchen.

Eine Ausführungsumgebung für die Skriptsprache PHP läuft je nach Betriebssystem als separater Dienst oder Prozess. Außer den Schnittstellen zu Webservern wie Apaches HTTPD oder Microsofts IIS bietet PHP keine standardisierten Objekt-Interfaces. Grundsätzlich gilt Letzteres auch für eine Java Virtual Machine (JVM). Will man nun PHP- und Java-Programme dazu bringen, miteinander zu reden, müssen geeignete Zwischenstücke her. Die docken sich an den rudimentären Schnittstellen der jeweiligen Prozesse an, ver- und entpacken übertragene Objekte, die die (für den Entwickler unsichtbare) Kommunikation über Prozessgrenzen hinweg abwickeln, und stellen Programmier-Interfaces (APIs) zur Verfügung.

Bei der Suche nach solchen Adaptern stößt man bald auf die PHP Java Extensions. Diese Erweiterungen nutzen das Object Overloading von PHP, um auf Java-Klassen zuzugreifen. Ruft ein PHP-Programm eine Java-Methode an einem Objekt auf, wird zuerst via Java Native Interface (JNI) eine JVM erzeugt. Der Rückgabewert lässt sich in den PHP-Seiten anzeigen. Die ersten Gehversuche mit dieser Lösung gestalten sich mühselig. Der Entwickler muss etliche Dinge konfigurieren, installieren, und die Kombination mit JNI verspricht nicht gerade sonderlich stabile Systeme. Unter Last geht diese Konstruktion schnell in die Knie. Schlimmstenfalls startet jeder Request eine komplette JVM. Für solche Experimente sollte ein Server mit großvolumigem Hauptspeicher zur Verfügung stehen. Instanz-Pooling oder andere Wiederverwertung findet hier nicht statt.

Eingebettete Experimente
Ähnliches lässt sich über die PHP-Servlet SAPI berichten. Sie bettet allerdings nicht Java in PHP ein, sondern PHP in Java: Ein Java-Webcontainer (etwa Tomcat) bekommt via Servlet eine PHP-Instanz eingebaut. Obwohl das SAPI-Modul auf den Mechanismen der PHP Java Extensions basiert, ist es stabiler und performanter. Vor allem deswegen, weil sich die Servlet Engine um das Pooling und das Recycling der JVMs kümmert und der PHP-Kern lediglich bei Bedarf geladen wird. Für beide Varianten finden sich Pro- und Kontra-Stimmen in einschlägigen Foren und Artikeln. Gefühlt überwiegen die Problemberichte. Aus diesem Grund sind die PHP Extension für PHP 5 als experimentell gekennzeichnet. Für produktive Umgebungen eignen sich beide Ansätze noch nicht.

Dem Java-Entwickler mögen die beiden Vorschläge befremdlich erscheinen, weiß er doch, dass mit Java 6 der Java Specification Request (JSR) 223 umgesetzt wurde. Dieser JSR beschreibt eine API, die einen Weg zum Einbinden von Skriptsprachen in die Java-Welt weist. Pro Sprache definiert der JSR eine sogenannte Scripting Engine. Zwar fördert die Suche in Suns Scripting-Projekt keine entsprechende Engine zutage, woanders findet man jedoch zwei Produkte, die die Scripting API für PHP umsetzen: Die PHP/Java Bridge auf Sourceforge und die native Java-Implementierung von PHP namens Quercus von Caucho. Die API reduziert den Gebrauch von PHP-Skripten in Java zum Vierzeiler:

ScriptEngineManager m = new ScriptEngineManager();
ScriptEngine phpEngine = m.getEngineByExtension("php");
ScriptContext context = phpEngine.getContext();
Object php2javaResult = phpEngine.eval("<"php echo \"hello world\";
?>",context);
Damit kann der Java-Entwickler auf einfache Weise Rückgabewerte von beliebigen PHP-Methoden und -Klassen in seine Programme übernehmen. Der Weg in die andere Richtung bleibt jedoch zunächst verschlossen. Allein ist die Scripting Engine nicht in der Lage, PHP-Dateien und -Klassen in einem Java-Applikationsserver auszuführen. Quercus beziehungsweise die PHP/Java Bridge liefern das notwendige Drumherum, dazu später mehr.

Zu den nativen Möglichkeiten gehört die PHP-Java-Interaktion mithilfe von Webservices. Hierbei geht es allerdings nicht um eine enge Verzahnung beider Welten, sondern lediglich um eine lose Zusammenarbeit. Dennoch hat diese Option ihren Reiz. Java EE kommt zwar ohne Probleme mit Webservices klar, auf der PHP-Seite muss man jedoch nachrüsten. Infrage kommen dafür etliche Frameworks, beispielsweise NuSOAP, ein Webservices-Toolkit für PHP. Allerdings müssen die Entwickler für diesen Weg auf beiden Seiten Schnittstellen schaffen und Übereinkünfte bezüglich der Zusammenarbeit treffen. Der Gewinn besteht in einer stabilen Lösung, die beide Seiten möglichst wenig beeinflusst. Allerdings muss man hier mit zwei separaten Infrastrukturen klarkommen.

Offen in alle Richtungen
Die im Folgenden vorgestellten Integrationsbemühungen gehen tiefer. Der JSR 223 bringt zwar dem Java-Entwickler PHP näher, seine PHP-Kollegen bleiben aber ohne nennenswerte Unterstützung. Dieses Manko wollen verschiedene Brücken beheben. Zur erwähnten PHP/Java Bridge existiert eine kommerzielle Alternative von Zend, der "PHP Company". Beide Produkte sind in der Lage, von PHP aus auf Plain Old Java Objects (POJOs) sowie andere Java- und Java-EE-Komponenten (EJBs, Connections, JMS et cetera) zuzugreifen. Die PHP/Java Bridge bietet zwei Zugriffsoptionen: Eine native, in PHP geschriebene Java-Brücke und ein in C umgesetztes PHP-Erweiterungsmodul. Der erste Weg lässt sich einfach beschreiten, man muss nur die relevanten PHP-Klassen auf den Webserver kopieren. Folgender Code-Schnipsel eröffnet den Zugriff auf Java-Klassen:

?php require_once("java/Java.php");
$string = new Java("java.lang.String", "HelloWorld");
echo $string;
?>;
Zum Ausführen benötigt diese Variante keinen nativen Code (.so oder .dll). Großes Manko: Im Gegensatz zum in C verfassten Modul läuft sie rund zehnmal langsamer. Dafür ist die Konfiguration des C-Moduls schwierig. Außer der JavaBridge.jar muss der Entwickler eine spezielle php_java.dll in den PHP-Erweiterungsordner (;/php/ext) kopieren und in (php.ini) registrieren. Unter Linux funktioniert das alles ohne installiertes Java; Windows verlangt hingegen ein Java Development Kit (JDK). Das einsatzbereite Modul kann beispielsweise folgenden Code ausführen:

$system = new Java('java.lang.System');
echo 'Java version=' . $system-> getProperty('java.version');
?>
Interessant ist die Tatsache, dass die PHP/Java Bridge ohne JNI auskommt. Neben den zwei beschriebenen Modulen und der Scripting Engine gibt es noch eine Mono-.Net-Brücke. Detaillierte Informationen dazu stehen auf der Projektwebseite.

Zend bietet im Rahmen seiner PHP-Plattform die Java Integration Bridge an. Leider gibt die Firmenwebsite dazu nicht allzu viel Wissenswertes preis. Erst der User Guide erschließt die Architektur des Produkts. Das Java Middleware Module folgt dem PHP-Standard. Der Zugriff sieht genauso aus wie bei der PHP/Java Bridge. Allerdings helfen hier einige Zusatzprogramme. Sowohl auf PHP- als auch auf Java-Seite wird eine Komponente installiert, die das Ein- und Auspacken der übertragenen Objekte besorgen.

Gute Lösung, etwas gebremst
Um die Wiederverwendung von Java-Instanzen und ein besseres Handling (Pooling, Threading et cetera) zu gewährleisten, startet man nicht einfach eine beliebige JVM und konfiguriert PHP zum Zugriff darauf, sondern aktiviert einen speziellen Dienst, der die Java-Instanzen verwaltet. Über diesen Service lassen sich sowohl Port als auch maximal verfügbare Prozesse einstellen. Die Kommunikation mit dem Java-EE-Applikationsserver erfolgt via Remote Method Invocation (RMI). Nachteil dabei: Ein PHP-Programm kann nur auf Objekte zugreifen, die über ein Remote-Interface verfügen. In Sachen Performance profitiert dieser Weg also nicht von den in der Java-Spezifikation verankerten Optimierungen, den EJB Local Interfaces. Nach eigenen Angaben arbeitet Zend zurzeit an dieser Baustelle. Es sei noch erwähnt, dass die Firma zwar zusammen mit Sun den JSR 223 ins Leben rief, bisher aber keine offizielle PHP-Engine für Java vorgestellt hat.

Wer mit den bisher beschriebenen Möglichkeiten nicht zurechtkommt, dem bleibt eine letzte Option. Neben der offiziellen PHP-Distribution gibt es die nach der GPL lizenzierte und in Java geschriebene Ausführung Quercus. Dieses Wunderwerk stammt, wie oben schon erwähnt, von der Firma Caucho, Hersteller des Applikationsservers Resin, der auch Quercus enthält. Quercus' Scripting Engine ist dieselbe wie bei der PHP/Java Bridge. Vorteile zieht der Entwickler aus den zusätzlichen Funktionen, die das Paket bereitstellt. Dazu zählen ein Servlet Wrapper für PHP-Aufrufe sowie die komplette Verwaltung der PHP-Instanz innerhalb des Webcontainers. Quercus lässt sich als Webapplikation (.war) herunterladen. Nach dem Auspacken muss der Programmierer diese Datei in das Anwendungsverzeichnis eines beliebigen Webcontainers schieben und schon steht ihm ein halbwegs aktuelles PHP 5.2 unter Java zur Verfügung. Damit ist es denkbar einfach, vorhandenen Java-Anwendungen PHP-Funktionen anzubieten. Zwei Java-Bibliotheken muss er noch in das WEB-INF/lib kopieren und das PHP Servlet in der web.xml registrieren:


PHPServlet

com.caucho.quercus.servlet.QuercusServlet



PHPServlet
*.php

Leider ist auch hier nicht alles so einfach, wie es zunächst scheint. Zwar stehen schon eine Menge PHP-Module für Quercus zur Verfügung (darunter APC, iconv, GD, gettext, JSON, MySQL, Oracle, PDF und Postgres) aber die komplette Palette deckt das Angebot noch nicht ab. Dennoch sind viele bekannte PHP-Anwendungen unter Quercus lauffähig, etwa DokuWiki, Drupal, Gallery2, Joomla, Mambo, Mantis, MediaWiki, Phorum, phpBB, phpMyAdmin, PHP-Nuke, Wordpress und XOOPS. Leider enttäuscht die kostenlose Version des Werkzeugs mit einem großem Nachteil: Datenbankzugriffe lassen sich nur per Java Naming and Directory Interface (JNDI) ausführen. Der normale PHP-Zugriff funktioniert nur in der lizenzpflichtigen Professional-Version des Application Server.

// PHP-DB-Zugriff
//mysql_connect($host, $username, $password, $dbname);
// JNDI-Zugriff mysql_connect("java:comp/env/jdbc/myDatabaseName");
Ebenfalls ein Schmankerl, in dessen Genuss nur die Professional-Lizenznehmer kommen: Quercus kann PHP-Quellen nicht nur zur Laufzeit interpretieren, sondern auf Wunsch auch vorkompilieren. In produktiven Umgebungen ergibt sich hier sicher ein Performancegewinn.

Es ist nicht möglich, eine pauschale Empfehlung für den richtigen Weg zu geben, zu unterschiedlich sind die Anforderungen. Wer in PHP-Webseiten gelegentlich einige Java-Funktionen verwenden möchte, muss eine andere Architektur aufbauen, als jemand, der eine Java-Webanwendung um PHP-Teile erweitern will. Das am häufigsten gewünschte Szenario ist vermutlich das anfangs skizzierte Java-Backend mit Geschäftsdaten im Zusammenspiel mit einer agilen und modernen PHP-Weboberfläche. Bei Unternehmen, die so etwas wollen, kann ein Produkt mit professionellem Support punkten – und hier bleibt nur Zends Java Integration Bridge. Wer nicht auf kommerzielle Unterstützung angewiesen ist, kann sich am PHP/Java-Bridge-Projekt auf Sourceforge versuchen. Am einfachsten gestaltet sich die Kommunikation über Webservices (XMLRPC/SOAP). Dafür braucht man in der Regel nicht einmal eine zusätzliche Architekturkomponente, bekommt allerdings auch keine integrierte Lösung.

PHP: Technische Grundlagen
Um eine PHP-Datei im Rahmen einer Webanwendung ausführen zu können, benötigt man ein System, das mit den im Sourcecode enthaltenen Anweisungen umgehen kann. Herkömmliche Webserver sind dazu nicht in der Lage. Sie bieten aber eine Schnittstelle (beispielsweise ISAPI oder CGI) für die Interpreter an. Sobald ein Webserver eine registrierte Datei (etwa *.php) ausliefern soll, übergibt sie ein Server-Daemon oder Dienst (zum Beispiel Apache oder IIS) an den Interpreter. Performant ist das Ganze jedoch nicht. Daher hat man dieses Vorgehen über die Jahre Stück für Stück durch Apache-Module abgelöst. Apaches Webserver bietet heute diverse Komponenten für die Zusammenarbeit mit Skriptsprachen. mod_php ist für das Einbinden des PHP-Interpreters zuständig.

Java EE und die Technik
Die Java-EE-Spezifikation stellt einen allgemein akzeptierten Rahmen bereit, in dem sich aus modularen Komponenten verteilte, mehrschichtige Anwendungen entwickeln lassen. Um eine Java-EE-Anwendung ausführen und betreiben zu können, benötigt man einen Applikationsserver, der Ausführungsumgebungen für die Komponenten zur Verfügung stellt. Zumeist enthält der Application Server einen Webserver, der das generierte HTML an den Browser ausliefert. Lediglich ein Teil der Java EE, nämlich die Java Server Pages (JSP) sind mit PHP-Seiten vergleichbar: Bei beiden handelt es sich um mit Code angereicherte HTML-Seiten. Im Gegensatz zu den PHP-Seiten werden JSPs beim erstmaligen Ausführen in Servlets konvertiert. Ein Servlet ist eine programmierte oder generierte Java-Klasse, die sich in einem Java-EE-Webcontainer ausführen lässt.

Quelle: http://www.heise.de/developer/
 
Keine Kommentare vorhanden.
Kommentar schreiben
Bitte einloggen um einen Kommentar zu schreiben.
 
Bewertungen
Bewertungen sind nur für Mitglieder möglich.

Bitte einloggen oder registrieren.

Keine Bewertungen abgegeben.