Einleitung
JCA Resource Adapter sind Java EE Architekturbausteine, die bei der Integration von Enterprise Information Systems (EIS) zur Anwendung kommen. Da die meisten Java EE Projekte hochgradig integrativ sind, sollten uns Resource Adapter Implementierungen auf Schritt und Tritt begegnen. Dennoch werden sie selten eingesetzt. Als Gründe kommen in Frage:
Outbound Resource Adapter
Ein Outbound Resource Adapter ist eine Java EE Ressource, die eine ausgehende Verbindung zu einem externen System über definierte Kontrakte vermittelt. Diese Kontrakte sind Connection Management (sprich: Connection Pooling), Transaktion Management (Einbindung in einen transaktionalen Kontenxt und Connection Sharing) und Sicherheit (Übergabe von Credentials).
Aber zunächst stelle ich ein Antipattern vor: Enterprise Integration über eine Java API. Die dahinter liegende Idee ist schnell vermittelt. Ein Java EE Projekt hängt von den Diensten eines EIS ab. Eine Java API mit der Clients das EIS ansprechen können steht zur Verfügung. In einer Java EE Umgebung werden dann Java EE Komponente (Servlets, Enterprise JavaBeans) über diese API Connections etablieren und mit dem EIS kommunizieren. Dieses Vorgehen hat mehrere Nachteile:
Outbound Resource Adapter lösen das Problem. Mit der Hilfe eines Outbound Resource Adapter wird ein vom Server verwalteter Pool mit physikalischen Connections aufgebaut. Den Java EE Komponenten werden vom Adapter lediglich Connection Handles zugeteilt, die temporär mit einer physikalischen Connection assoziiert sind. Wird das Connection Handle geschlossen, geht die assoziierte physikalische Connection in den Pool zurück. Um Deadlocks zu vermeiden werden innerhalb einer Transaktion alle EIS Aufrufe von ein und derselben ManagedConnection Instanz erledigt. Dafür muss die ManagedConnectionImpl Connection Sharing unterstützen, der Container assoziiert immer das in der Transaktion aktive Connection Handle mit der ManagedConnection Instanz. Details werden im zweiten Teil des Artikels beleuchtet.
In einer allgemeineren Sicht kann der Outbound Resource Adapter bei jeder Art schwer zu beschaffender Ressourcen die nicht nebenläufig verwendet werden dürfen zum Einsatz kommen. Ein schönes Beispiel ist ein javax.xml.transform.Transformer. Bei seiner Instanziierung werden XSL Transformationen geladen, ein potentiell aufwändiger Prozess. Ein solcher Transformer sollte deshalb für viele Transformationen verwendet werden, gleichzeitig darf er aber nicht nebenläufig genutzt werden. Hier wäre Instanzen-Pooling die Methode der Wahl, eine Pool-Implementierung ist aber nicht so einfach und kann, da sysnchronisierter Code verwendet wird, nicht im Kontext einer EJB genutzt werden. Die saubere Lösung bestünde darin, Transformer-Instanzen über Outbound Resource Adapter zu kapseln. Instanzen-Pooling wird dann vom Container bereitgestellt!
Outbound Resource Adapter Logik wird immer im Context des Clients ausgeführt ("the resource adapter serves as a passive library for connecting to an EIS, and executes in the context of the application threads"), ein Outbound Resource Adapter ist also keine remote arbeitende Komponente! Praktisch heißt das, das EIS wird immer von der Anwendungsinstanz aus gerufen. Im Grunde stellt der Container lediglich die Klassen des Adapters bereit und (über den ConnectionManager) eine Connection-Pool Implementierung. Die Clients eines Outbound Resource Adapter sind damit immer serverseitige Komponente (Servlets, EJB oder MDB) die auf der gleichen Serverinstanz laufen.
Outbound Resource Adapter können vom Servlet Container und vom EJB Container als Ressource genutzt werden.
Inbound Resource Adapter
Ein Inbound Resource Adapter ist eine Java EE Serverkomponente, die eingehende Nachrichten externer Systeme über definierte Kontrakte an Message Driven Beans vermittelt. Diese Kontrakte sind Messaging Inflow, Messaging Delivery und Transaktion Inflow. Zusätzlich benötigt der Inbound Resource Adapter den WorkManager des Servers für den Empfang und die Abarbeitung eingehender Nachrichten. Inbound Resource Adapter stehen seit JCA 1.5 zur Verfügung.
Ein Inbound Resource Adapter ergänzt die Möglichkeiten mit einem Java EE Server zu kommunizieren, beliebige auf TCP + UDP/IP basierende, Nachrichten verteilende EIS können asynchron angebunden werden:
| Java EE Komponente | Inhalt | Protokoll | Transportlayer | Verarbeitung |
|---|---|---|---|---|
| Servlet | HTML | http | TCP/IP | synchron |
| Session/Entity Bean | serialisierte Objekte (RMI) | IIOP oder JRMP | TCP/IP + UDP/IP | synchron |
| Message Driven Bean | javax.jms.Message | JMS proprietär | TCP/IP | asynchron |
| Webservice Endpoint | SOAP | http | TCP/IP | synchron |
| Inbound Resource Adapter | beliebig | beliebig | TCP/IP + UDP/IP | asynchron |
Der Inbound Resource Adapter ist somit eine aktive Komponente: beim Start des Servers wird ein Service Thread aktiviert, der letzlich einen ServerSocket instanziiert und auf eingehenden Nachrichten wartet. Die Abarbeitung der Nachrichten erfolgt über Worker Threads, die vom Service Thread mit der Hilfe des WorkManagers instanziiert werden.
Eine Variante bei der Implementierung betrifft den Service Thread. Statt einen ServerSocket zu instanziieren kann er auch via Polling ein EIS auf Nachrichten abfragen. Details werden im dritten Teil des Artikels beleuchtet.
Referenzen
Brauchbare Bücher zum Thema sind nicht zu finden (ich bitte um einen Hinweis, wenn ich mich da irre). Die beste Quelle für Detailfragen ist meines Erachtens immernoch die JCA Spezifikation.
Zum Connection Sharing hat IBM einen brauchbaren Artikel ins Netzt gestellt.
Gute technische Übersicht für Outbound Resource Adapter: The J2EE Connector Architecture's Resource Adapter
Connect the enterprise with the JCA, Part 1
Develop inbound connectors with JCA 1.5
Develop and deploy a JCA 1.5 compliant connector in jBoss 4
Creating Resource Adapters with J2EE Connector Architecture 1.5
Introduction to J2EE Connector Architecture