Start - Publikationen - Wissen - TOGAF - Impressum -

Einleitung


Java Connector Architecture (JCA) Resource Adapter sind Java EE Architekturbausteine, die bei der Integration von Enterprise Information Systems (EIS) zur Anwendung kommen. Da die meisten Java EE Anwendungen hochgradig integrativ sind, sollten uns Resource Adapter Implementierungen auf Schritt und Tritt begegnen. Dennoch werden sie selten eingesetzt. Als Gründe kommen in Frage:

  • Resource Adapter sind die Implementierungen einer Schnittstelle, die mehrere Server-Laufzeitkontrakte gleichzeitig erfüllt - entsprechend anspruchsvoll ist eine Umsetzung und Beispielimplementierungen sind schwer zu finden.
  • Die JCA Spezifikation ist umfangreich. Darüber hinaus ist sie zum Teil aus der Sicht der Server-Provider (und nicht der Resource Adapter-Implememtierer) formuliert.
  • Die Verantwortung zur Entwicklung und Pflege der Resource Adapter läge in den Händen der EIS-Betreiber. Diese müssten dafür recht ausgeprägtes Java EE Wissen bereithalten. Das ist aber bei den meisten Organisationen eine unrealistisch Annahme, das Java EE Wissen ist normalerweise ausschließlich in den mit der Integration beauftragten Java EE Projekten vorhanden.
Dieser Artikel beschäftigt sich mit der Implementierung von Resource Adapter. Zunächst wird der Unterschied zwischen Outbound und Inbound Resource Adapter erläutert und welche architektonischen Probleme beide Typen lösen. Für beide Resource Adapter wird eine Beispielimplementierung angeboten und ausführlich kommentiert.

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 (insbesondere 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:

  • Die Konfiguration der API ist nur über die Environment Einträge der Komponenten möglich und muss redundant erfolgen. In einer Java EE Umgebung ist es einsichtiger, eine EIS-Anbindung als Komponente bereitzustellen, die von anderen Komponenten als Service benutzt wird.
  • Vom Container bereitgestellte Dienste (security, single sign on, transaction handling) sind schwierig oder gar nicht zu integrieren.
  • Die Java API repräsentiert während ihrer Benutzung eine physikalische Verbindung zu einer Ressource der Systemlandschaft. Wenn diese Ressource aufwändig zu beschaffen ist kann Connection Management (Connection Pooling) eine wichtige (die einzige!) Strategie zur Vermeidung von Ressourcen-Engpässen sein. Connection Management ist ein weiterer vom Container bereitgestellter Dienst, den eine Java API nicht bieten kann.
Der letzte Punkt ist entscheidend, Connection Pooling kann auf der Ebene der Businesslogik nicht improvisiert werden. Ich bezeichne die Anbindung eines EIS über eine Java API deshalb als Antipattern.

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 ist "passiv" und wird wenn dann im Context der aufrufenden Komponente ausgeführt ("the resource adapter serves as a passive library for connecting to an EIS, and executes in the context of the application threads"). Aufrufende Komponente sind dabei immer andere Java EE Komponente, wie Servlets oder EJB.

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 basierende, Nachrichten verteilende EIS können asynchron angebunden werden:

Java EE Komponente Inhalt Protokoll Transportlayer Verarbeitung
Servlet HTML http TCP synchron
Session/Entity Bean serialisierte Objekte (RMI) IIOP oder JRMP TCP + UDP synchron
Message Driven Bean javax.jms.Message JMS proprietär TCP asynchron
Webservice Endpoint SOAP http TCP synchron
Inbound Resource Adapter beliebig beliebig TCP + UDP 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

copyright © 2003-2021 | Dr. Christian Dürr | prozesse-und-systeme.de | all rights reserved