Isolationsprobleme in Java Transaktionen

Werbung
Isolationsprobleme in Java Transaktionen
- Java Spektrum –
•
Robert Harbach, Wolfgang Rosenstiel, Wilhelm G. Spruth
• Abstract
Using Threads the Java Virtual Machine (JVM) is able to support several
applications in parallel. Since, however, the JVM does not enable real
application isolation, hosting several applications in one JVM can be critical if
these applications represent transactions. Therefore, the common practice
found in most Java application servers implies to run one JVM per
application. Due to the fact, that this implies an overhead of computational
resources, several, most often proprietary, solutions for application isolation in
JVMs have been proposed in the past. This publication outlines isolation
properties of a new JVM type, called a JVM Server that is integrated into the
Customer Information Control System (CICS) [Ray11]. It implements the
OSGi framework [OSG11b] and leads to major improvements in terms of
application isolation. However, it is also shown that several known problems
remain unsolved. Within this paper, solutions to these isolation exposures are
proposed. Some of them are not based on the official Java release; others
use existing CICS services for program control and are thus not applicable
across the board.
• Zusammenfassung
Die Java Virtual Machine (JVM) ist in der Lage, mit Hilfe von Threads
mehrere Anwendungsprogramme gleichzeitig zu betreuen. Dies kann kritisch
sein, wenn es sich dabei um Transaktionen handelt, da die JVM keine echte
Applikationsisolation
ermöglicht.
Das
Hosting
eines
einzigen
Anwendungsprogramms pro JVM ist deshalb eine übliche Vorgehensweise,
was häufig einen ineffizienten Verbrauch von Rechenleistung zur Folge hat.
Aus diesem Grund wurden bereits mehrere, meist proprietäre, Lösungen zur
Applikationsisolation in JVMs vorgestellt. Diese Veröffentlichung beschreibt
die Isolationseigenschaften eines neuen Typs der JVM, welche in das
Customer Information Control System (CICS) [Ray11] integriert ist. Sie
implementiert das OSGi Framework [OSG11b] und erreicht damit wichtige
Verbesserungen. Es wird aber gezeigt, dass viele bekannte
Isolationsprobleme weiterhin bestehen. Hierzu werden praktische
Lösungsansätze als Abhilfe vorgeschlagen. Einige sind nicht Bestandteil des
existierenden Java Standards. Andere nutzen bestehende CICS Services zur
Kommunikation zwischen Programmen und sind somit nicht universell
einsetzbar. Auf die Notwendigkeit einer langfristigen Lösung wird
hingewiesen.
1. Einleitung
Unternehmen und staatliche Organisationen verfügen heute über eine komplexe IT
Infrastruktur. In großen Unternehmen besteht diese häufig aus Tausenden von
Servern, zuständig für Aufgaben wie Sicherung des Netzwerks und der
Applikationen, Routing und Switching, sowie das Hosting von (Web-)Applikationen.
Dabei erfolgt die zentrale Datenhaltung auf einem oder mehreren Mainframe Servern
(deutsche Bezeichnung Großrechner) mit dem z/OS Betriebssystem. Es besteht eine
kritische Abhängigkeit der Unternehmen von ihren Datenbeständen. Deshalb haben
Anwendungsprogramme, welche die Datenbestände einer Organisation abändern,
meistens transaktionale Eigenschaften. Ein Anwendungsprogramm ist dann eine
Transaktion, wenn es die ACID Eigenschaften (Atomicity, Consistency, Isolation,
Durability) erfüllt [Gra93].
Transaktionen werden in den meisten Fällen mittels einer Middleware ausgeführt, die
als Transaktionsmonitor oder Transaktions-Server bezeichnet wird. Diese stellt unter
anderem mit Hilfe von Scheduling- und Synchronisationsmechanismen sicher, dass
jede Transaktion strikt die ACID Eigenschaften implementiert. Zudem stellen die
meisten Transaktionsmonitore bestimmte Services zur Kommunikation zwischen
Anwendungen zur Verfügung. Darüber hinaus wird die Wiederherstellung des
Datenbestands nach fehlerhaft ausgeführten Transaktionen ermöglicht (Stichwort
Rollback).
Verbreitete Transaktionsserver sind Tuxedo (BEA/Oracle), CICS (IBM), MTS
(Microsoft) und SAP R/3. In den letzten 12 Jahren entstanden zusätzlich Web
Application Server, welche für Transaktionen in der Programmiersprache Java
entwickelt wurden. Beispiele sind Weblogic (BEA/Oracle), WebSphere (IBM) und
NetWeaver (SAP) sowie Open Source Produkte wie Geronimo, Glassfish und JBoss.
Transaktionen sind häufig „unternehmenskritische“ Anwendungen. Wir bezeichnen
damit solche Anwendungen, deren fehlerhafte Ausführung zu nicht tolerierbaren
Konsequenzen führt. Ein Beispiel ist ein Rundungsfehler in der letzten Dezimalstelle
bei der Ausführung einer finanziellen Transaktion. Falls dieser Fehler auftritt, muss
er, notfalls in tagelanger manueller Arbeit, identifiziert und rückgängig gemacht
werden.
2. Problemdefinition
Ein transaktionales Anwendungsprogramm besteht häufig aus den zwei
Komponenten: Präsentationslogik und Geschäftslogik (Business Logic). Während die
Geschäftslogik die eigentliche Arbeit verrichtet, dient die Präsentationslogik dazu, die
Ergebnisse der Geschäftslogik auf eine attraktive Art auf dem Bildschirm
darzustellen. In der populären Model View Controller Triade entspricht das Modell
der Geschäftslogik und der View der Präsentationslogik [Moe93].
Seit der Einführung von Java im Jahr 1995 existiert ein Interesse, die Sprache auch
für transaktionale Anwendungen einzusetzen. Hierzu erschien 1999 die als Java
Enterprise Edition (JEE) bezeichnete Erweiterung. Während Java für die
Implementierung der Präsentationslogik seitdem einen Siegeszug angetreten hat,
erfolgte der Einsatz für die Geschäftslogik unternehmenskritischer Anwendungen
bisher nur sehr zögerlich.
Hierfür existieren mehrere Gründe. Ein wichtiger Grund sind unzureichende
Eigenschaften, welche die Isolation (I in ACID) der Transaktionen sicherstellen.
Isolationsprobleme der JVM sind seit Einführung des JEE-Standards bekannt, siehe
z. B.:
„The existing application isolation mechanisms, such as class loaders, do not
guarantee that two arbitrary applications executing in the same instance of the JVM
will not interfere with one another. Such interference can occur in many places. For
instance, mutable parts of classes can leak object references and can allow one
application to prevent the others from invoking certain methods. The internalized
strings introduce shared, easy to capture monitors. Sharing event and finalization
queues and their associated handling threads can block or hinder the execution of
some application. Monopolizing of computational resources, such as heap memory,
by one application can starve the others [Cza00]“.
Oder:
„Java gives the virtuoso thread programmer considerable freedom, but it also
presents many pitfalls for less experienced programmers, who can create complex
programs that fail in baffling ways [San04]“.
3. Bisherige Lösungsansätze
In der Vergangenheit sind eine Reihe von Lösungsvorschlägen entwickelt worden.
Diese wurden jedoch häufig wieder verworfen.
Die meisten Isolationsprobleme einer JVM basieren auf der Tatsache, dass die JVM
über keine Ressourcen-Management Funktionen verfügt. Spezifisch wurde die JVM
nicht für den Betrieb mehrerer Applikationen entworfen. Aus diesem Grund läuft in
vielen Applikationsservern pro Anwendung eine virtuelle Maschine. Dadurch wird
sichergestellt, dass Anwendungen sich gegenseitig nicht beeinflussen. Dieses
Vorgehen führt jedoch zu einer ineffizienten Nutzung der Ressourcen, insbesondere
im Zusammenhang mit der Erstellung und dem Abbau der einzelnen JVMs. Ein
vielversprechender Ansatz zur Lösung der Isolationsprobleme war die Application
Isolation API [Jav06]. Obwohl dieser Ansatz die meisten Isolationsprobleme
beseitigte, wurde die Application Isolation API bisher in keinem offiziellen Java
Release veröffentlicht.
Ein weiterer interessanter Ansatz zur Lösung bestehender Isolationsprobleme in
JVMs war die Persistent Reusable Java Virtual Machine (PRJVM) [IBM01], die
speziell für den CICS Transaktions-Server entwickelt wurde. Die PRJVM
implementierte einen Mechanismus für die Wiederherstellung des Status der VM vor
etwaigen Programmausführungen. Obwohl dieser Ansatz einen Ausgleich zwischen
effizientem Ressourcenverbrauch und Applikationsisolation darstellte, wurde die
PRJVM von einer neuen JVM-Implementierung, dem „JVM Server“, ersetzt. Ein JVM
Server ist eine Laufzeitumgebung der JVM innerhalb von CICS, die eine Standard
JVM mit einem OSGi Framework enthält. Anwendungen laufen innerhalb dieses
Frameworks als so genannte Bundles. Ein Bundle besteht aus einem Java Archive
(jar) und einer Inhaltsbeschreibung (MANIFEST.MF).
Die vorliegende Veröffentlichung beschreibt im folgenden einige der heute
existierenden Isolationsprobleme und diskutiert Lösungsmöglichkeiten. Manche
Lösungsansätze benötigen hierzu Funktionen der Middleware, in der die JVM
eingesetzt wird, und sind deshalb nicht portierbar. Unsere Untersuchungen basieren
auf die Version der JVM, welche in dem „JVM Server“ des CICS Transaction Servers
Version 4.2 seit 2011 verfügbar ist.
CICS (Customer Information Control System) ist ein Transaktionsmonitor der Firma
IBM mit Applikationsserver Funktionalität. Die wichtigsten Gründe für den Einsatz von
CICS als Applikationsserver sind, neben seiner weiten Verbreitung in Enterprise
Systemen, die zahlreichen verfügbaren Services, die unter anderem
Transaktionssicherheit ermöglichen. Darüber hinaus agiert CICS als Middleware und
ermöglicht dadurch den Betrieb unterschiedlicher Anwendungen ungeachtet der
verwendeten Programmiersprache. Damit ist eine einheitliche Kommunikation
zwischen Anwendungen möglich.
4. Java Integration in CICS
CICS unterstützt seit 1998 das Hosting von Java Applikationen [IBM11-c]. Typisch
basiert die Java Unterstützung auf einem Pool von JVMs. Diese Lösung wird in
Zukunft durch den JVM Server ersetzt. Im Folgenden werden die zwei verschiedenen
Modelle der Java Unterstützung beschrieben.
4.1 Pooled JVMs
Ein Pool von JVMs ist eine Laufzeitumgebung für eine vordefinierte Anzahl an JVMs
innerhalb vom CICS. Diese Laufzeitumgebung stellt sicher, dass in jeder JVM nur
eine Anwendung, bzw. Transaktion, gleichzeitig aktiv ist. Die JVMs werden von den
einzelnen Transaktionen seriell verwendet (siehe Abbildung 1).
Abbildung 1: Grafische Darstellung der seriellen Verwendung von Pooled JVMs
durch mehrere Transaktionen. Nach [IBM11-b].
Wie in [IBM11-b] beschrieben haben die JVMs innerhalb des Pools drei
verschiedene Betriebsmodi:
•
Single Use
◦
Neuerstellung der JVM nach erfolgter Transaktion
•
Reusable
◦
Wiederverwendung der JVM für mehrere aufeinanderfolgende Transaktionen
•
Resettable (auch Persistent Reusable Virtual Machine genannt, siehe
[IBM01])
◦
Wiederherstellung des Zustandes der JVM nach erfolgter Transaktion
Auf einem Hochleistungsserver werden mehrere hundert oder tausend
Transaktionen pro Sekunde verarbeitet. Trotz der Isolationsvorteile des „Single Use“
Modus, ist dieser für viele Anwendungen nicht geeignet, da die Dauer der Erstellung
einer neuen JVMs im hohen Millisekundenbereich angesiedelt ist. Auch der
Reusable Modus birgt Nachteile. Beispielsweise kann eine Anwendung durch die
Modifikation einer statischen Systemvariable einen direkten Einfluss auf
nachfolgende Anwendungen haben, falls diese nicht wieder zurückgesetzt wird.
Unter Berücksichtigung der Eigenschaft, dass der Resettable Mechanismus ebenfalls
Zeit in Anspruch nimmt, kann auch der Resettable Modus nur bedingt als geeigneter
Lösungsansatz der Isolationsprobleme betrachtet werden.
Die Ressourcenprobleme in Pooled JVMs werden durch den neuen CICS JVM
Server verbessert.
4.2 JVM Server
Ein JVM Server ist eine Laufzeitumgebung für die Ausführung von CICS Java
Applikationen. Diese beinhaltet nur eine JVM und wird von mehreren Anwendungen
parallel verwendet. Zudem enthält der JVM Server ein OSGi Framework (siehe
Abbildung 2), welches die Isolation und die Modularität von Anwendungen
ermöglicht. Dabei wird die Isolation mit Hilfe von Class Loadern bewerkstelligt, eine
Methode, die bereits 1997 von Balfanz und Gong [Bal97] beschrieben wurde und
auch in JEE verwendet wird [Chi09]. Dieser Ansatz basiert auf der Eigenschaft, dass
Objekte, die von unterschiedlichen Class Loadern erstellt wurden, sich in
unterschiedlichen Namensräumen befinden und somit keinerlei Kenntnis
voneinander besitzen. Wie jedoch in [Mcg99] beschrieben, besteht kein Schutz
gegen eine Überschneidung der Namensräume (siehe Kapitel 5).
Abbildung 2: Grafische Darstellung der JVM Server Laufzeitumgebung in CICS
Das OSGi Framework kapselt Anwendungen bzw. Funktionen (je nach gewünschter
Granularität) in sogenannte Bundles, die laut [IBM11-b] auch als Plain Old Java
Objects (POJOs) [Fow00] betrachtet werden können. Ein Bundle hat mehrere
Zustände, darunter Uninstalled, Installed, Resolved und Active [OSG11b]. Die
Administration der Zustände der Bundles innerhalb einer aktiven JVM erfolgt mit Hilfe
des OSGi Frameworks. Dies ermöglicht die Installation einer neuen Anwendung in
den JVM Server ohne Neustart der JVM. Im Gegensatz dazu ist bei den meisten
Java Applikationsservern ein Neustart für ein erfolgreiches Deployment einer neuen
Anwendung notwendig.
Die Zustände der Bundles werden in der Regel über ein Interface gesteuert – die
OSGi Konsole. Im Falle des JVM Servers wird dieses Interface durch den CICS
Explorer, eine auf Eclipse basierende Anwendung, repräsentiert.
Da jedes Bundle einen eigenen Class Loader besitzt, sind Objekte standardmäßig
voneinander isoliert. Diese Art der Isolation ist jedoch unvollständig [Mue05]. Im
folgenden Abschnitt wird dies näher erläutert.
5. Offene Isolationsprobleme in JVMs
Im Rahmen unserer Untersuchung wurden die Erkenntnisse von Müller [Mue05],
sowie Erkenntnisse von Parrend und Frenot [Par09], berücksichtig. [Mue05] zeigte
bereits 2005 eine größere Anzahl von JEE Isolationsproblemen auf. [Par09]
beschreibt Isolationsprobleme des OSGi Frameworks. Basierend auf den
Erkenntnissen von [Mue05] und [Par09] wurde in praktischen Versuchen überprüft,
welche bekannten Probleme der JVM und dem OSGi Framework in einen
transaktionalen System basierend auf CICS anwendbar sind. Hierfür wurde, wie
oben beschrieben, die JVM Server Laufzeitumgebung in CICS verwendet.
Im Detail wurden die folgenden Probleme praktisch nachgebildet. Die einzelnen
Versuche und Ergebnisse inklusive verwendetem Quellcode sind in [Har12-a]
beschrieben.
Aus Gründen der Vereinfachung werden im folgenden OSGi Bundles als
Anwendungen bzw. als Transaktionen interpretiert.
5.1: Probleme mit Systemklassen
Da, wie in [Cza00] beschrieben, Systemklassen nicht repliziert werden und die Class
Loader Isolation somit keinen Einfluss auf die Systemklassen hat, sind die bekannten
Probleme, die auch Müller in [Mue05] beschrieben hat, wie die Manipulation von
statischen Feldern oder der Zugriff auf potentiell gefährliche Methoden von
Systemklassen auch im JVM Server nicht behoben.
Ändert beispielsweise Klasse A aus Bundle X die Dateitrenner (file separator)
Systemeigenschaft mit Hilfe der setProperty Methode der Systemkasse System, so
ist diese Änderung global und somit für Klasse B aus Bundle Y sichtbar. Des
Weiteren ist es nach wie vor möglich, die gesamte JVM mit Hilfe der Methode exit
der Systemklasse System (oder der Methode halt der Systemklasse Runtime) zu
beenden.
Da jede Anwendung in einer JVM einen Thread repräsentiert (siehe [Lin99]), kann
zudem die auch Verwendung einiger Methoden der Systemklasse Thread zu großen
Problemen führen. Beispielsweise ist es mit Hilfe der Methode getAllStackTraces
möglich auf einzelne Threads zuzugreifen und diese mit Hilfe der deprecated
Methode suspend zu beenden.
Der Zugriff auf Systemklassen und deren Methoden kann aus jeder Klasse (und
jedem Bundle) stattfinden; somit repräsentiert jeder einzelne genannte Fall ein
Isolationsdefizit.
5.2: Überschneidende Namensräume
Aufgrund der Benutzung verschiedener Class Loader und der daraus resultierenden
Namensräume, sind einzelne Bundles standardmäßig voneinander isoliert. Bei
Verwendung eines Features des OSGi Frameworks, dem so genannten „wiring“
(siehe [OSG11b]), kann Isolationseffekt der Class Loader umgangen werden. Wiring
ermöglicht generell die Kommunikation zwischen Bundles. Hierfür kann ein Bundle
bestimmte Klassen exportieren und diese dadurch für andere Bundles zur Verfügung
stellen. In einigen Fällen führt diese Überschneidung der Namensräume jedoch zu
Problemen. Exportiert beispielsweise Bundle A die Klasse A, die von verschiedenen
Bundles importiert wird, so wird wie in [Lip08] beschrieben basierend auf dem
Delegationsmechanismus (siehe [OSG11b]), der gleiche Class Loader für die
Erstellung aller Instanzen (aus allen Bundles) der Klasse A verwendet. Statische
Variablen aus Klasse A sind somit für alle Instanzen aus allen Bundles global.
Noch gravierender ist der konkurrierende Zugriff zwischen Bundles mit Hilfe von
Threads. In diesem Fall werden Synchronisationsprobleme zu Isolationsproblemen,
da durch Rata Races Bundles einen undefinierten Einfluss aufeinander haben
können und somit gegen die Isolationseigenschaft von Transaktionen verstossen.
Der Einsatz von Synchronisationsmechanismen kann in diesem Fall nur bedingt als
Lösung angesehen werden, da hängende Threads in synchronisierten Methoden zu
mehreren hängenden Bundles und somit zu Anwendungsübergreifenden Deadlocks
führen können. Dies repräsentiert erneut ein Isolationsdefizit.
5.3: Das Java Native Interface
Wie in [She99] beschrieben, ermöglicht Java die Ausführung von
platformabhängigem C/C++ Code. Hierfür stellt die JRE eine Schnittstelle namens
Java Native Interface (JNI) zur Verfügung. Mit dessen Hilfe können C/C++
Anwendungen aus eine Java Klassen heraus gestartet werden. Wichtig zu erwähnen
ist, dass die gestarteten C Anwendungen Zugriff auf den Stack und den Heap der
JVM haben.
In diesem Zusammenhang hatte Müller [Mue05] gezeigt, dass Probleme wie
Segmentation Faults im platformanhängigen Code durch den Absturz der JVM alle
aktiven Anwendungen beeinträchtigen. Der gleiche Effekt trat auch in unserer
Testumgebung auf. Darüber hinaus wurde auch gezeigt, dass das JNI die
unrechtmäßige Manipulation von privaten Variablen auch im CICS Umfeld
ermöglicht. Grund hierfür ist die Eigenschaft der Programmiersprache C, die keine
Zugriffsklassen (access modifier) für Variablen vorsieht. Folglich ist die Manipulation
einer privaten Variable, abgelegt im Stack, möglich.
5.4: Übermäßiger Ressourcenverbrauch
Wie bekannt, besitzt Java keinerlei Funktionen zur Verwaltung der Ressourcen. Aus
diesem Grund darf jede Applikation innerhalb einer JVM so viele Ressourcen
verbrauchen wie nötig. Ein übermäßiger Ressourcenverbrauch hat jedoch enorme
Auswirkungen auf andere Applikationen, die in der gleichen JVM aktiv sind. In
diesem Zusammenhang wurden übliche Probleme, unter anderem beschrieben in
[Par09], wie Endlosschleifen, rekursive Erstellung von Threads und Memory Leaks
im CICS Umfeld untersucht. Darüber hinaus wurde ein OSGi spezifisches Problem
nach [Par09], die endlose Registrierung von Services, umgesetzt.
Recht trivial aber dennoch gravierend sind Endlosschleifen. Diese konsumieren laut
[Par09] viel Rechenleistung und können somit zu einer Verlangsamung anderer
Applikationen führen. In unserem Versuchsaufbau führten Endlosschleifen sogar zu
einem Neustart der JVM und somit zu einem Abbruch aller aktiven Applikationen.
Der Grund hierfür ist eine Vorsichtsmaßnahme des Transaktionsmanagers CICS,
welches die Endlosschleife erkennt und dadurch einen kontrollierten Neustart der
Applikationen hervorruft. Da die JVM jedoch mehrere Applikationen betreut, führt ein
Neustart der JVM zu einem Abbruch aller Java Anwendungen.
Ein weiteres Beispiel entnommen aus [Par09] für übermäßigen
Ressourcenverbrauch ist die rekursive Erstellung von Threads. Diese führen schnell
zu JVM Neustarts.
Etwas komplexer aber dennoch problematisch sind so genannte Memory Leaks. Ein
Memory Leak ist in der Regel ein Fehler im Programmcode, welcher die
automatische Speicherbereinigung, die so genannte garbage collgection, für
bestimmte Objekte außer Kraft setzt. Wie in [Nyl99] beschrieben, gehen viele
Entwickler aufgrund der garbage collection in JVMs davon aus, dass Java frei von
Memory Leaks ist. [Din04] beschreibt jedoch, dass Java Objekte nur gelöscht falls
auf diese nicht referenziert wird. In einigen Fällen ist dieses Vorgehen nicht effektiv,
da nicht referenzierte Objekte sich dennoch im Heap befinden können. In praktischen
Versuchen, dokumentiert in [Har12], wurden Memory Leaks im JVM Server
umgesetzt. Die Ergebnisse zeigen, dass auch unter der Kontrolle von CICS, Java
Memory Leaks zu Isolationsproblemen führen, da entweder der Speicherbereich
verkleinert wird oder, falls die maximale Heap Größe überschritten wird, CICS einen
JVM Neustart durchführt. Ein ähnliches Verhalten zeigt der JVM Server auch bei
unendlichen Service Registrierungen. Wie in [Par09] beschrieben, kann eine
Anwendung eine unendliche Menge an OSGi spezifischen Services registrieren. Dies
führt ebenfalls zur Überschreitung des maximalen Speichers und somit zu einem
Neustart der JVM.
Die Ergebnisse zeigen, dass alle untersuchten Probleme zu Denial of Service führten
und somit in JVM Servern gültig sind.
5.5: Probleme mit Activator Klassen
Das OSGi Framework beinhaltet sogenannte Activator Klassen (siehe [OSG11b]).
Diese werden beim Start und beim Beenden der Bundles aufgerufen und dienen dem
Entwickler zur Erstellung von Objekten und deren Bereinigung beim Start bzw. beim
Beenden des Bundles. Parrend und Frenot haben in [Par09] mit Hilfe dieser Klassen
bei Implementierung einer Endlosschleife und eines hängenden Threads ein Denial
of Service Problem hervorgerufen. Dies führte zu einer aufgehängte
Administrationsoberfläche. Obwohl diese Klassen in JVM Servern nicht benötigt
werden (siehe [IBM11-b]), ist deren Verwendung nicht untersagt. In einem
praktischen Beispiel wurde das Problem nach [Par09] reproduziert. Trotz der
Tatsache, dass der JVM Server explizit nur über das CICS Explorer Interface
administriert wird, erhielten wir ähnliche Resultate wie in [Par09]; sprich eine
Aufhängung des CICS Explorers.
Somit gelten die Probleme aus [Par09] im Bezug auf Activator Klassen
uneingeschränkt auf den JVM Server.
5.6: Unrechtmäßige Kontrolle
Wie in [OSG11b] beschrieben stellt das OSGi Framework bestimmte Services für die
Verwaltung der Zustände von Bundles zur Verfügung. Mit Hilfe dieser kann ein
Bundle andere Bundles steuern und gegebenenfalls deinstallieren. Obwohl diese
Funktionalität in vielen Fällen sinnvoll scheint, stellt sie aus Sicht der
Anwendungsisolation ein Problem dar. Hinzu kommt das in [Par09] beschriebene
Problem bezüglich der Fragment Bundles. Ein Fragment stellt eine nachträgliche
Erweiterung eines Bundles nach dessen Deployment dar. Dadurch werden
Modifikationen am Bundle ohne größere Probleme bewerkstelligt. Laut [OSG11b]
sind Übersetzungsdateien für Applikation einer der hauptsächlichen
Anwendungsfälle. Nun kann ein Fragment die Sichtbarkeit von Klassen mit Hilfe der
wiring Funktionalität (sprich export einer Klasse) eines Bundles verändern ohne dass
dieses davon Kenntnis bekommt. Dies kann zu unerlaubten Überschneidungen der
Namensräume führen und stellt somit ebenfalls ein Problem im Bezug auf
Applikationsisolation dar.
6. Praktische Lösungsansätze
Um Abhilfe unter Einbindung bestehender, real existierender, Möglichkeiten im
Bezug auf die offenen Isolationsprobleme zu schaffen, wurden praktische
Lösungsansätze untersucht. Diese werden im Folgenden aufgelistet (Details in
[Har12-a]).
6.1 Statische Programmanalyse
Wie in [Rep04] beschrieben, dient statische Programmanalyse dazu alle möglichen
Status eine Applikation ohne spezifische Eingabedaten zu überprüfen. In der Regel
werden diese Analysen automatisch mit Hilfe von Tools bewerkstelligt.
Im Bezug auf Systemklassen stellt die Application Isolation Utility, beschrieben in
[IBM11-a], eine passende Lösung dar. Das Tool untersucht den Programmcode einer
Java Anwendung und identifiziert Zugriffe auf Methoden der Systemklassen und
statische Variable sowie deren Manipulation.
Weitere Tools wie FindBugs (siehe [Aye07]) können zur Identifikation von
Endlosschleifen verwendet werden und minimieren das Risiko eines Denial of
Service (siehe 5.4).
6.2 Java und OSGi Security
Java beinhaltet standardmäßig die Möglichkeit zur Programmkontrolle mit Hilfe des
Java Security Managers. Nach Aktivierung laufen alle kritischen Operationen, wie
Zugriffe auf Systemklassen, lokale Ressourcen oder Threads unter der Kontrolle des
Security Managers. Berechtigungen werden als „white list“ in einer policy file
vergeben. Darüber hinaus kann der Security Manager nach Belieben erweitert
werden. Dadurch kann der Zugriff auf potentiell schädliche Methoden von
Systemklassen wie exit unterbunden werden.
Neben dem Standard Java Security Manager enthält der JVM Server aufgrund des
OSGi Frameworks einen weiteren Security Layer. Dieser ist im Grunde genommen
ein modifizierter Security Manager, der OGSi spezifische Berechtigungen,
beispielsweise zur gegenseitigen Kontrolle der Bundles, beinhaltet. Damit können
alle Probleme im Bezug auf Systemklassen (siehe 5.1) sowie alle Probleme im
Bezug auf unrechtmäßige Kontrolle (siehe 5.6), gelöst werden.
6.3. Monitoring
Obwohl die meisten statischen Programmanalyse-Tools offensichtliche Probleme wie
Endlosschleifen erkennen, ist das Problem des übermäßigen Ressourcenverbrauchs
bei deren Einsatz nicht vollständig gelöst. Probleme wie hängende Threads, Memory
Leaks oder simple übermäßige Nutzung des Speichers bleiben offen. Um
diesbezüglich dennoch Abhilfe zu schaffen, eigen sich Monitoring Tools, die den
Zustand der JVM in Echtzeit überwachen. In unserer Testumgebung auf CICS
bewährten sich der JVM Server spezifische Monitor namens Java Health Center
(siehe [IBM]). Diese erkannten Memory Leaks und größeren Speicherverbrauch in
Echtzeit.
Trotz der Tatsache, dass Monitoring manuelle Interaktion voraussetzt, ist diese
Lösung als praktischer Lösungsansatz die einzige derzeitige Möglichkeit um Denial
of Service spezifische Isolationsdefizite zu beheben.
6.4 CICS Services
In einigen Fällen ist es unabdingbar platformabhängigen Code zu verwenden. Da
CICS als Middleware zwischen Anwendungen agiert und somit spezifische Services
zur Kommunikation zwischen Applikationen ermöglicht, ist die Lösung aller Probleme
im Bezug auf das Java Native Interface (siehe 5.3), die Verwendung von CICS
Services zur Kommunikation anstatt des JNI. Mit Hilfe dieser Services ist selbst die
Kommunikation transaktional und bringt somit einige Vorteile mit sich.
7. Schlussfolgerung und Ausblick
Es wurde gezeigt, dass die meisten bekannten Isolationsprobleme auch innerhalb
eines transkationsbasierten Enterprise Umfelds gültig sind. Die meisten untersuchten
Probleme können jedoch mit Java oder Framework spezifischen Bordmitteln gelöst
werden. Ungelöste Probleme wie Endlosschleifen oder hängende Threads können
zumindest mit bestimmten Tools identifiziert werden.
Allein hängende Threads in Activator Klassen konnten weder behoben noch zur
Laufzeit identifiziert werden, da ein hängendes Management Interface, in unserer
Testumgebung der CICS Explorer auch das live Monitoring, in unserem Fall das
Java Health Center, beeinflusst.
Trotz all der Vorteile bringen die Lösungsansätze auch einige Nachteile mit sich.
Statische Programmanalyse beispielsweise garantiert nicht die Erkennung
potentieller Probleme und kann somit nicht als verlässliche Lösung angesehen
werden. Wie in [Her05] gezeigt, kann der Java Security Manager eine Applikation
stark verlangsamen; und obwohl keine vergleichbaren Publikationen zum OSGi
Security Layer verfügbar sind, kann davon ausgegangen werden, dass diese
Verlangsamung auch im Falle des OSGi Security Layers auftreten kann. Auch CICS
Services kommen nicht ohne Nachteile, denn sollte eine Anwendungen diese
tatsächlich verwenden, ist einer der wichtigsten Vorteile von Java, die
Platformunabhängigkeit, nicht mehr gegeben, da stets CICS als Middleware für die
Anwendung vorausgesetzt wird.
Es bleibt jedoch abzuwarten welche Entwicklungen im Bereich des OSGi
Frameworks zukünftig erfolgen werden. Ein spekulativer Ansatz zur Lösung der
vorgestellten Defizite wird in einer parallel im Informatik Spektrum erscheinenden
Veröffentlichung [Har12-b] beschrieben.[R.H.1]
Ein vielversprechender nicht spekulativer Ansatz, erwähnt in einem frühen Entwurf
der aktuellen OSGi Framework Spezifikation (siehe [OSG10]), beschreibt die
Isolation von Bundles durch Erstellung mehrerer sogenannter „Nested Frameworks“.
Diese sind komplett voneinander isoliert und kommunizieren nur über standardisierte
Schnittstellen miteinander und könnten somit unter Umständen als Alternative zum
OSGi Security Layer dienen.
1.
Literatur
[Aye07] N. Ayewah, W. Pugh, J. D. Morgenthaler, J. Penix, Y. Zhou, Evaluating
Static Analysis Defect Warnings On Production Software. In: Proceedings of the 7th
ACM SIGPLAN-SIGSOFT workshop on Program analysis for software tools and
engineering, PASTE ’07, S. 1–8, New York, NY, USA, 2007. ACM.
http://findbugs.cs.umd.edu/papers/FindBugsExperiences07.pdf
[Bal97] D. Balfanz, L. Gong, Experience with Secure Multi-Processing in Java.
Technical report, Department of Computer Science, Princeton University September
1997. http://sip.cs.princeton.edu/pub/icdcs.pdf
[Chi09] R. Chinnici, B. Shannon, Java Platform, Enterprise Edition (JavaEE)
Specification, v6, October 2009. http://download.oracle.com/otndocs/jcp/javaee- 6.0fr-oth-JSpec/
[Cza00] G. Czajkowski, Application Isolation in the Java Virtual Machine.
In: Proceedings of the 15th ACM SIGPLAN conference
on Object-oriented programming, systems, languages, and applications.
New York : ACM Press, 2000, S. 354–366.
http://research.sun.com/projects/barcelona/papers/oopsla00.pdf
[Din04] A. Dingle. Reclaiming Garbage and Education: Java Memory Leaks. J.
Comput. Small Coll., 20:8 - 16, Dezember 2004
[IBM] IBM Corp, IBM Monitoring and Diagnostic Tools for Java - Health Center
Version 2.0. Webseite.
http://www.ibm.com/developerworks/java/jdk/tools/healthcenter/
[IBM01] IBM Corp, New IBM Technology featuring Persistent Reusable Java Virtual
Machines, Oktober 2001. http://www03.ibm.com/systems/resources/servers_eserver_zseries_software_java_pdf_prjvm13
.pdf
[IBM11-a] IBM Corp, CICS Transaction Server for z/OS Version 4 Release 2:
Upgrading from CICS TS Version 3.1, 2011.
http://publib.boulder.ibm.com/infocenter/cicsts/v4r2/topic/com.ibm.cics.ts.migration.do
c/dfheg_pdf.pdf
[IBM11-b] IBM Corp, Java Applications in CICS (Version 4 Release 2), 2011.
http://publib.boulder.ibm.com/infocenter/cicsts/v4r2/topic/com.ibm.cics.ts.java.doc/dfh
pj_pdf.pdf
[IBM11-c] IBM Corp, Techreport: History of CICS. Webseite, 2011. https://www304.ibm.com/support/docview.wss?uid=swg21025234
[Gra93] J. Gray, A. Reuter, Transaction Processing. Morgan, Kaufman, 1993
[Fow00] M. Fowler, Webseite, 2000. http://www.martinfowler.com/bliki/POJO.html
[Fri02] G. Friesen. Java 2 by Example. Que, Indianapolis, IN, 2nd edition, 2002
[Har12-a] R. Harbach, CICS JVM Server Application Isolation. Masterarbeit am
Wilhelm-Schickard-Institut für Informatik der Universität Tübingen, März 2012
[Har12-b] R. Harbach, W. Rosenstiel, W. Spruth, Isolation in Java Transaktionen,
INFORMATIK SPEKTRUM Veröffentlichung erscheint demnächst.
[Her05] A. Herzog, N. Shahmehri, Performance of the Java security manager.
Computers & Security, 24(3):192 – 207, 2005.
http://rewerse.eu/publications/download/REWERSE- RP- 2005- 141.pdf
[Lin99] T. Lindholm, F. Yellin. The Java Virtual Machine Specification. AddisonWesley Longman Publishing Co., Inc., Boston, MA, USA, 2nd ed edition, 1999.
http://java.sun.com/docs/books/jvms/second_edition/html/VMSpecTOC.doc.html
[Lip08] M. Lippert. Classloading and Type Visibility in OSGi. Presentation slides,
2008. http://www.martinlippert.org/events/WJAX2008ClassloadingTypeVisibilityOSGi.pdf
[Mcg99] G. McGraw, E. Felden. Securing Java. John Wiley & Sons, Inc., Januar
1999. http://www.securingjava.com
[Moe93] Hanspeter Mössenböck. Objektorientierte Programmierung. Springer, 1993,
ISBN 3-540-55690-7
[Mue05] J. Mueller, Anwendungs- und Transaktionsisolation unter Java, Mai 2005.
http://www-ti.informatik.uni-tuebingen.de/~spruth/DiplArb/jmueller.pdf
[Nyl99] J. Nylund. Memory Leaks in Java Programs. Application Development
Trends, Dezember 1999. http://adtmag.com/articles/1999/12/24/memory-leaks-injava-programs.aspx
[OSG10] OSGi Alliance, Version 4.3 Core Early Draft 1, April 2010.
http://www.osgi.org/download/osgi- core-4.3-early-draft1.pdf
[OSG11b] OSGi Alliance, OSGi Service Platform Core Specification Release 4
Version 4.3, April 2011. http://www.osgi.org/download/r4v41/r4.core.pdf
[Par09] P. Parrend, S. Frénot, Security benchmarks of OSGi platforms: towards
Hardened OSGi. Softw. Pract. Exper., 39:471–499, April 2009
[Ray11] C. Rayns, S. Bertram, G. Bogner, C. Carlin, A. Clark, A. Ferrell, G. Keehn, P.
Klein, R. Lee, E. Woerner, CICS Transaction Server from Start to Finish. IBM
International Technical Support Organization (ITSO), December 2011.
http://www.redbooks.ibm.com/redbooks/pdfs/sg247952.pdf
[Rep04] T. Reps, M. Sagiv, R. Wilhelm, Static Program Analysis via 3-Valued Logic.
In Ra jeev Alur and Doron Peled, editors, Computer Aided Verification, volume 3114
of Lecture Notes in Computer Science, S. 401–404. Springer Berlin / Heidelberg,
2004. http://groups.csail.mit.edu/cag/crg/papers/reps04shape.pdf
[San04] B. Sandén, Coping with Java Threads. IEEE Computer, Vol. 37, Nr. 4, April
2004, S. 20
[She99] L. Sheng, The Java Native Interface: Programmer’s Guide and Specification.
Java series. Addison-Wesley, Reading, MA, 1999.
http://java.sun.com/docs/books/jni/download/jni.pdf
Alle in digitaler Form verfügbaren Aufsätze sind zusätzlich in einem Mirror unter
http://www-ti.informatik.uni-tuebingen.de/~spruth/Mirror/Java_Spektrum/index.html
abrufbar.
Herunterladen