Die Kommunikation

NextDie Modulverwaltung von ISA erweitert den Standard Java ClassLoading Mechanismus um die Fähigkeit mit dynamischen Modulen umgehen zu können. Daher kann innerhalb von Modulen auf alle Klassen und Ressourcen, die von einem importierten Modul exportiert werden auch mit Standard Java Mitteln zugegriffen werden. (z.B. Modul-B nutzt Modul-A)

//META-INF/MANIFEST.MF ModulA-1.0.0[
//  PlugIn-Exports: AuftragsVerwaltung; AuftragsPosition
//]
//META-INF/MANIFEST.MF ModulB[
//  PlugIn-Imports: ModulA[version=1.0.0]
//]
public class ModulB{
  ...	
    
  AuftragsVerwaltung av = new AuftragsVerwaltung(); 

  //aus ModulA
  AuftragsPosition pos = new AuftragsPosition();

  //aus ModulA	
  pos.setAuftragsNummer("4711");	
  av.getAuftrag("XY").addPosition(pos);
  
  ...
}

Diese Art der Codierung ist mit den bekannten Nachteilen bzgl. Kopplung, fehlender Trennung zwischen Implementierung und Schnittstelle oder direkter Instantiierung behaftet.

Aus diesem Grund bietet die Modulverwaltung zusätzlich eine gesteuerte Inter-Modul-Kommunikation an, die folgende Bereiche abdeckt.

  • Kommunikation einer nicht ISA Anwendung – mit ISA Modulen
  • Kommunikation über Rechner- und Plattformgrenzen
  • Kommunikation zwischen ISA Modulen

Der Basismechanismus ist dabei eine generische Call Schnittstelle auf der im Weiteren dann eine typisierte, proxybasierte Service Schicht aufsetzt.

Generische Schnittstelle

public class ModuleFoo{
  ...
  
  //generischer Aufruf von doBizzService des Moduls ModuleBar-1.0.0
  handler.call("ModuleBar:doBizzService[version=1.0.0]", new Object[]{arg1, arg2});
  
  ...
}

Diese Schnittstelle trennt zunächst den Aufrufer physisch vollständig von dem aufgerufenen Modul und ermöglicht gleichzeitig der Verwaltung die vollständige Kontrolle (Interception) über den Aufruf und sein Empfängermodul.

Um den Nachteilen einer solchen untypisierten Programmierung entgegen zu wirken bietet die Modulverwaltung darauf aufbauend eine “Service” Schnittstelle, die anonyme, dynamische Objekte liefert, die eine gegebene Schnittstelle (Java Interface) realisieren.

Proxy bzw. Service Schnittstelle

public class ModuleFoo{

  //das Java Interface von ModuleBar
  //für typisierten Methodenaufruf auf einem Proxy
  ModuleBarIFace bar = null;	

  ...

  //Service von der Verwaltung beschaffen	
  bar = (ModuleBarIFace)handler.getService("ModuleBar[version=1.0.0]", ModuleBarIFace.class);

  //typisierter Methodenaufruf	
  bar.doBizzService(arg1, arg2);

}

Bei diesem Verfahren wird intern ein Standard Java Proxy mit einem InvocationHandler erzeugt, der die entsprechenden Aufrufe wieder an die “call” Schnittstelle der Modulverwaltung weiterleitet. Auf diese Weise bleibt die physische Entkopplung der beteiligten Module trotz strenger Typisierung vollständig erhalten. Zudem existieren KEINE echten Referenzen auf Modulinstanzen außerhalb der Modulverwaltung.

Um die Programmierung weiter zu verschlanken unterstützt das System auch die Einbindung von Diensten, Ressourcen und individuellen anderen Objekten über frei definierbare Annotationen.

Annotations und Dependency Injection

public class ModuleFoo{

  //die Modulkonfiguration	
  @Resource(Type.CONFIG)	
  protected Map config = null;	
  
  //Dienste eines anderen Moduls (Client oder Server)	
  //als injiziertes Proxy	
  //die Version wird über die Imports automatisch ermittelt	
  @Service()	
  protected ModulBarIFace bar = null;	
  
  //z.B. eigene spezielle Fachobjekte oder Dienste	
  @MyBizzAnnotation()	
  protected AuditTrail audit = null;	...	
  
  //typisierter Methodenaufruf	
  MyBizzData ret = bar.doBizzService(arg1, arg2);
  
  ...
}