next up previous contents
Nächste Seite: 6.4 Sichere Kanäle Aufwärts: 6. Implementierungskonzept Vorherige Seite: 6.2 Der ORB und   Inhalt

Unterabschnitte


6.3 Ausführungsumgebungen von Agentensystem und Agenteninstanzen


6.3.1 Änderungen in Klassen Agent/AgentSystem/AgentManager

Abbildung 6.4: Klasse Agent - Vererbung und Package-Struktur der bisherigen Implementierung
\begin{figure}
\centering\includegraphics [width=0.7\textwidth]{AgentPackOld_argo}\end{figure}

Um den in Kap. 5.3 geforderten Speicherschutz von Agenteninstanzen (und des Agentensystems selbst) realisieren zu können, ist in Java nach Abschnitt 6.1.1 durch die fehlende Zeigerarithmetik bereits eine gute Basis vorhanden. Um nun auch tatsächlich unerwünschte Zugriffe auf Attribute und Methoden von Agentenklassen und Klassen des Agentensystems verhindern zu können, müssen nur die in Abschnitt 6.1.1 vorgestellten Visibilitätsmodifikatoren konsequent eingesetzt werden.

Die Grundvoraussetzung für diesen Ansatz, nämlich die jeweils getrennten Packages von Agentensystem und allen Agentengattungen ist bereits in der bestehenden MASA-Implementierung realisiert.


Für die Sicherung des Zugriffs auf Attribute sollte generell auf die Möglichkeit des direkten Zugriffs auf Attribute durch andere Klassen verzichtet werden. Stattdessen sollten Zugriffsmethoden angeboten werden, die es ermöglichen, lesend (get-Methode) bzw. schreibend (set-Methode) auf das Attribut zuzugreifen. Entsprechend sollte der Visibilitätsmodifikator eines Attributs immer private lauten. Neben der Möglichkeit der Unterscheidung zwischen lesenden/schreiben Zugriffen in der Autorisierung, was bei direkten Attributzugriffen nicht möglich ist, bietet dieses Vorgehen noch den Vorteil, daß bei schreibenden Zugriffen zusätzlich eine Überprüfung auf semantische Korrektheit des zu setzenden Wertes durchgeführt werden kann.

Für Klassen, die als interne Klassen des Agentensystemems bzw. einer Agentengattung fungieren, läßt sich dies einfach erreichen, indem die Klasse als Package deklariert wird. Damit können alle Attribute, unabhängig von ihrem Visibilitätsmodifikator nur noch aus dem eigenen Package angesprochen werden. Für Klassen, die public deklariert sein müssen, weil sie Methoden für Klassen aus anderen Packages bereitstellen (dies gilt insbesondere für jene Klassen, die CORBA-Methoden implementieren), muß der Zugriffsschutz durch die Visbilitätsmodifikatoren der einzelnen Attribute gewährleistet werden.

In diesem Zusammenhang müssen besonders die Basis-Klassen agent.Agent und deren Tochterklassen agent.StationaryAgent und agent.MobileAgent beachtet werden. Um den in Kap. 3.4.1 geschilderten Bedrohungen entgehen zu können muß eine Reorganisation dieser Klassen vorgenommen werden.

Da die Klasse agent.Agent kritische Attribute und Methoden enthält (vgl. Kap. 3.4.1), die u.a. vom Agentensystem für die Verwaltung einer Agenteninstanz benötigt werden und auf die eine Agenteninstanz aber höchstens lesend zugreifen darf, müssen diese in einer Klasse deklariert werden, die im Package agentSystem liegt. Diese neue Klasse wird AgentEnvironment genannt und soll in Zukunft alle Attribute und Methoden aufnehmen, die einer Agenteninstanz zuordenbar sind. Am Beispiel der Methode setThread(), die nur vom Agentensystem benötigt wird, betrachtet: Die Umdeklarierung der Methode zu package oder private ist nicht möglich. Zwar könnte die Agenteninstanz sie dann nicht mehr nutzen, das Agentensystem aber ebenfalls nicht. Wird setThread() aber in der Klasse AgentEnvironment deklariert, kann sie mit package-Sichtbarkeit deklariert werden, wodurch nur noch Klassen des Agentensystems Zugriff haben.

Um den lesenden Zugriff auf Attribute durch die Agenteninstanz aber zu ermöglichen, wird die Klasse agent.Agent von AgentEnvironment abgeleitet. Wird dann die get()-Methode eines Attributs protected deklariert, kann auch die Agenteninstanz das Attribut lesen, da die get()-Methode von der Agenteninstanz erreicht werden kann.

Abbildung 6.5: Klasse Agent - Neue Vererbung und Package-Struktur
\begin{figure}
\centering\includegraphics [width=0.7\textwidth]{AgentEnviron1_argo}\end{figure}

Der Vorteil der in der bisherigen Implementierung gemachten Ansiedelung charakteristischer Attribute in der Basis-Klasse agent.Agent liegt darin, daß diese im Fall der Serialisierung einer Agenteninstanz (z.B. zur Migration) automatisch mitserialisiert werden, da jede Gattung indirekt immer von agent.Agent abgeleitet ist. Dieser Vorteil geht aber nicht verloren, da agent.Agent von agentSystem.AgentEnvironment abgeleitet ist. Die automatische Serialisierung der Attribute ist durch die Ableitung weiterhin gewährleistet, durch die unterschiedlichen Packages der Klassen ist der statische Zugriffsschutz aber weiterhin gewährt.


6.3.2 Laufzeitumgebung

Für die in Kap. 5.3 geforderten getrennten Laufzeitumgebungen für Agenteninstanzen bietet sich die Verwendung von Threads und ThreadGroups als Laufzeitmodell an.

Abbildung 6.6: Threads der bestehenden Implementierung
\includegraphics [width=5.0cm]{thread_impl_aktuell}

In der bestehenden Fassung von MASA werden allerdings noch nicht alle Möglichkeiten genutzt, die Java bietet, um Threads gegeneinander abzuschotten. Zwar werden Threads, die zu Agenteninstanzen gehören in einer eigenen ThreadGroup zusammengefaßt und so von Threads des Agentensystems getrennt, aber es wird keine Unterscheidung zwischen Threads von verschiedenen Agenteninstanzen getroffen. Folglich besteht kein Schutz gegen die Einflußnahme auf Threads durch fremde Agenteninstanzen.

Weiterhin ist von Seiten des Agentensystems nur der Haupt-Thread, nämlich jener, der durch das Agentensystem bei Erzeugung der Instanz gestartet wird, identifizierbar. Sub-Threads, die eine Instanz selbst erzeugt hat, können nicht identifiziert werden. Dies hat zur folge, daß bei Terminierung einer Instanz die Sub-Threads nicht zwangsweise terminiert werden können, vielmehr ist das Agentensystem hier auf die Kooperation der Instanz angewiesen.

Abbildung 6.7: Eigene ThreadGroups für Agenteninstanzen
\includegraphics [width=5.0cm]{thread_impl_neu}

Um eine solche Einflußnahme ausschließen zu können müssen demnach alle Threads, die zu einer Agenteninstanz gehören in einer eigenen ThreadGroup zusammengefaßt werden. Durch den SecurityManager ist es dann möglich, Zugriffe auf fremde Threads zu erkennen und zu verhindern.

Damit werden auch Sub-Threads einer Agenteninstanz identifizierbar, da diese immer in der ThreadGroup der Instanz erzeugt werden. Damit kann durch das Agentensystem alleine gewährleistet werden, daß bei Terminierung wirklich alle zur Instanz gehörenden Threads gestoppt werden.

6.3.3 Namensräume: Der Java Classloader

Nachdem nun auch getrennte Laufzeitumgebungen für Agenteninstanzen geschaffen sind, ist nur noch dafür Sorge zu tragen, daß keine Namenskonflikte zwischen Agenteninstanzen und besonders zwischen einer Agenteninstanz und dem Agentensystem auftreten können.

Die Trennung von Namensräumen wird in Java durch sogenannte Classloader ([JDK1.2-SDK]) bewerkstelligt. Ein Classloader ist eine spezielle Klasse, die für das Laden von Code zuständig ist und vom runtime linker der JVM angesprochen wird.

Ein Namensraum besteht nun aus allen Klassen, die von der gleichen Instanz eines Classloader geladen wurden. Folglich ist es für die Trennung der Namensräume zwischen Agenteninstanzen notwendig, daß jeder Agenteninstanz eine eigene Instanz eines Classloaders vom Agentensystem zugewiesen wird.

Hierfür erzeugt das Agentensystem, bevor es die Hauptklasse der Agentengattung instanziiert, eine neue Classloader-Instanz. Durch diese lädt das Agentensystem dann den Code der Hauptklasse aus dem Code Repository. Erst dann wird die Hauptklasse instanziiert. Jede weitere Klasse, welche die Hauptklasse benötigt, wird dann automatisch durch diesen Classloader geladen. Damit werden alle Klassen, die die Agenteninstanz benutzt, vom gleichen Classloader geladen und die Instanz hat einen eigenen getrennten Namensraum.


next up previous contents
Nächste Seite: 6.4 Sichere Kanäle Aufwärts: 6. Implementierungskonzept Vorherige Seite: 6.2 Der ORB und   Inhalt
harald@roelle.com