Microsofts .Net-Wende

05.10.2001
Von 
Wolfgang Sommergut ist Betreiber der Online-Publikation WindowsPro.
MÜNCHEN (COMPUTERWOCHE) - Geprägt durch seine Ursprünge als Desktop-System für nicht vernetzte Umgebungen behindert Windows immer stärker Microsofts Ambitionen, führender Software-Lieferant für das Internet zu werden. Mit .NET wirft die Gates-Company fast alles über Bord, was ihr bisher lieb und teuer war. Stattdessen macht sie massive Anleihen bei Java und Unix.

Fragwürdige Design-Entscheidungen, die Microsoft-Ingenieure teilweise schon Anfang der neunziger Jahre trafen und die sich zunehmend als Altlasten bemerkbar machen, hätten schon eine gründliche Rennovierung von Windows gerechtfertigt. Vor allem aber zeigen laufend publizierte Sicherheitsprobleme sowie die extreme Anfälligkeit für Virenangriffe immer deutlicher, dass sich grundlegende Konzepte des Microsoft-Systems nicht für eine global vernetzte Welt eignen.

Anwender erfahren die Auswirkungen dieses nicht mehr zeitgemäßen Computing-Modells allzu oft in Form mangelhafter Stabilität und Sicherheit ihrer Arbeitsumgebung. Besonders die ungeschützte Ausführung von Code birgt im Internet-Zeitalter zu viele Gefahren - anders als zur Entstehungszeit von Windows, wo Anwender ihre Programme fast ausschließlich noch über den Handel bezogen.

   Die Akzeptanz eines neuen Systems wie .NET hängt wesentlich davon ab, ob es bestehende Programme integrieren kann. Zur Einbindung von COM-Objekten nutzt Microsoft eine Wrapper-Technologie (Quelle: David Platt, Microsoft Press).  
   Die Akzeptanz eines neuen Systems wie .NET hängt wesentlich davon ab, ob es bestehende Programme integrieren kann. Zur Einbindung von COM-Objekten nutzt Microsoft eine Wrapper-Technologie (Quelle: David Platt, Microsoft Press).  

Microsoft macht aus den bestehenden Defiziten seiner Plattform kein Hehl. Vielmehr hat es sich fast schon eingebürgert, dass Firmenvertreter eine neue Software anpreisen, indem sie an der alten Version kaum ein gutes Haar lassen. Auf der diesjährigen europäischen TechEd in Barcelona gab der Chefarchitekt von .NET, Anders Hejlsberg, unumwunden zu, dass sich Windows in der gegenwärtigen Form als Innovationsbremse für Microsofts Internet-Pläne erwiesen habe. Konferenzteilnehmer erfuhren in anderen Vorträgen zudem, dass Distributed COM (DCOM) ein Fehlschlag war, das Windows-Programmiermodell über die einzelnen Sprachen und Tools hinweg inkonsistent, COM zu kompliziert und das Win32-API mit seinen mittlerweile rund 5000 Funktionen zu unübersichtlich sei. Seit längerer Zeit gehören bei Microsoft-Konferenzen auch saloppe Sprüche über die "DLL Hell" zum Standardprogramm. Gemeint sind damit Versionskonflikte bei Laufzeitbibliotheken, die von mehreren Programmen gemeinsam genutzt werden.

Abstürze oder Fehlfunktionen von Windows-Programmen gehen nicht nur auf DLL-Konflikte zurück, sondern haben ihre Ursachen häufig in anderen Systemspezifika: so können beschädigte Einträge in der Registrierdatenbank eine Applikation außer Gefecht setzen. Der wohl häufigste Grund für Abstürze freilich dürften Speicherschutzverletzungen sein, wenn sich bei C++-Code Fehler in der expliziten Speicherverwaltung einschleichen.

Die imposante Mängelliste, die Microsoft mittlerweile nicht mehr in Abrede stellt, gibt eine ganze Reihe grundlegender Verbesserungen vor, die .NET zu leisten hat: Dazu zählen die Vereinheitlichung des Programmiermodells für alle Sprachen, Schutz vor schädlichem Code, robustere Anwendungen durch automatische Speicherverwaltung, eine einfache und stabile Architektur für verteilte Applikationen sowie die Vermeidung von Versionskonflikten und Konfigurationsproblemen.

Es liegt auf der Hand, dass derart weitreichende Änderungen nicht mehr ohne weiteres mit dem bisherigen Ausführungsmodell von Programmen vereinbar sind und einen radikalen Umbau des Microsoft-Systems erfordern. Tatsächlich verabschiedet sich die Gates-Company von vielem, was bis dato als unabkömmlicher Bestandteil von Windows galt. Dazu zählen die Registrierdatenbank ebenso wie das Component Object Model (COM) oder das Portable-Executable-(PE-)Programmformat.

Auch wenn Microsofts Marketing Verwirrung stiftet, indem bestehende Produkte wie die Backoffice-Server reihenweise mit dem .NET-Namenszusatz versehen werden, so repräsentiert doch das .NET-Framework das Kernstück der neuen Strategie. Es umfasst zwei Hauptkomponenten, die Common Language Runtime (CLR) und die Common Language Infrastructure (CLI). Bei ersterer handelt es sich um eine virtuelle Maschine, die nicht nativen Maschinencode ausführt, sondern Programme, die in Microsofts Intermediate Language vorliegen. Diese MIL befindet sich gegenüber dem Gastsystem auf der gleichen Abstraktionsstufe wie Java-Bytcode, die CLR stimmt in ihrer Funktionsweise weitgehend mit der Java Virtual Machine (JVM) überein (siehe dazu "Close up on .NET" von Paul Young). Microsoft reklamiert jedoch, dass die MIL nie für die Ausführung durch einen Interpreter konzipiert wurde, sondern von Anfang an als Input für eine Just-in-Time-Compiler (JIT) gedacht war. Deshalb seien solche Programme kompakter als Java-Bytecode und liefen auch schneller ab.

Als zusätzliche Schicht zwischen Betriebssystem und Anwendung kann die CLR zwei wesentliche Mängel bisheriger Programmausführung beheben: Die automatische Speicherverwaltung (garbage collection) beseitigt eine wesentliche Fehlerquelle traditioneller Softwareentwicklung unter Windows. Im Gegensatz zum bisherigen Programmlader, der auch schädlichen Anwendungen freien Lauf lässt, ist sie zudem in der Lage, die Programmausführung zu überwachen. Das umfasst nicht nur vor dem Start die Überprüfung des Codes auf unzulässige Anweisungen (vergleichbar dem Bytecode Verifier von Java), sondern auch strenges Type-Checking und die Untersuchung der Programmdateien auf mögliche nachträgliche Veränderungen. Ähnlich wie Java seit der Version 1.1 besitzt .NET ein fein abgestuftes Rechtesystem, das abhängig von der Herkunft des Codes regeln kann, auf welche Systemressourcen dieser in welcher Form (lesend/schreibend) zugreifen darf.

Während die CLR als Ausführungsumgebung notorische Windows-Sicherheitsprobleme lösen könnte, soll der zweite Baustein des Frameworks, die Common Language Infrastructure, eine einheitliche Programmier-Schnittstelle für alle Sprachen bieten. Nach dem Vorbild des Package-Konzepts von Java gruppiert sie logisch zusammengehörige Funktionen des darunter liegenden Win32-API in einem hierarchischen Namensraum. Allerdings kapselt sie diese in Objekte, der .NET-Entwickler hat es mit einer vollständig objektorientierten Umgebung zu tun. Im Gegensatz zu COM unterstützt diese die Vererbung von binären Objekten, auch wenn diese in anderen Programmiersprachen erstellt wurden. Wegen der Unterschiede zwischen den einzelnen .NET-Sprachen gibt es da jedoch gewisse Einschränkungen. Wenn beispielsweise in C++ Pointer verwendet werden, lassen sich derartige Objekte in Visual Basic (VB) nicht nutzen. Deshalb definierte Microsoft eine Common Language Specification (CLS), die festlegt, welche Sprach-Features die sprachübergreifende Verwendung von Komponenten erlauben.

Schluss mit der DLL-Hölle

Hinsichtlich der leidigen DLL-Versionskonflikte und der bisher undurchsichtigen Programmkonfiguration verspricht das neue Konzept Besserung: Aufgrund der detaillierten Versionsinformationen und der intern beschriebenen Dateiabhängigkeiten können verschiedene Ausführungen eines Programms oder einer DLL sogar gleichzeitig nebeneinander genutzt werden (Side-by-side execution). Die selbstbeschreibenden .NET-Programme benötigen keine Einträge in der Registrierdatenbank. DLLs, die von mehreren Anwendungen gemeinsam genutzt werden, finden ihren Platz üblicherweise in einem zentralen Verzeichnis. Dieses dient in Microsofts Sprachregelung als Global Assembly Cache (GAC). Applikationen, die dort keine Komponenten hinterlegen - so verkündete ein Sprecher auf der Teched stolz - , könnten durch einfaches Löschen des Verzeichnisses entfernt werden, ohne dass sie Spuren im System hinterlassen.

Während diese Idealkonstellation tatsächlich auf die Dienste der Registrierdatenbank verzichten kann, hat dieses zentrale Repository in der Praxis noch lange nicht ausgedient. Zum einen wird es von bestehenden Windows-Anwendungen und COM-Komponenten benötigt, zum anderen müssen .NET-Programme ihre Metadaten als Type Libraries exportieren, wenn sie von Legacy-Programmen über COM-Mechanismen angesprochen werden sollen. Für die Interaktion zwischen der COM- und .NET-Welt verwendet Microsoft zwei Sorten von Hüllen: Damit .NET-Programme auf COM-Server zugreifen können, nutzen sie einen Runtime Callable Wrapper (RCW). Umgekehrt sehen .NET-Objekte für COM-Komponenten dank dem COM Callable Wrapper (CCW) wie ihresgleichen aus. Die Integration von .NET und COM ist weitgehend mit jener vergleichbar, die Microsoft bereits mit der hauseigenen JVM vorlegte: Auch dort lassen sich Java-Klassen ebenfalls als COM-Objekte ansprechen, und die Kommunikation in die andere Richtung funktioniert ebenfalls.

Ohne Kompatibilität mit COM hätte es .NET wohl schwer, die Akzeptanz der Anwender zu gewinnen. Die Brücken zwischen den beiden Welten dienen indes nicht nur dazu, alten Code in der neuen Umgebung weiterverwenden zu können. Im ersten Schritt kann Microsoft nämlich .NET-Komponenten noch nicht direkt für objektbasierte Transaktionen verwenden. Der in COM+ aufgegangene Transaction Server (MTS) nimmt .NET-Objekte nur dann auf, wenn sie über entsprechende Registry-Einträge als COM-Komponenten erscheinen. Native .NET-Transaktionsobjekte nach dem Muster von Suns "Enterprise Javabeans" erfordern eine Erneuerung von Microsofts Transaktionssystem.

Da COM und .NET auf den meisten Windows-Rechnern auf längere Sicht koexistieren müssen, hat ihre Integration große Bedeutung. Weniger Rücksicht auf die installierte Basis muss Microsoft bei verteilten Anwendungen auf Basis von DCOM nehmen, weil diese Technik kaum Verbreitung fand. Dort bricht die Gates-Company deshalb mit der Vergangenheit und sieht für solche Applikationen eine Architektur vor, die mittlerweile unter der Bezeichnung "Web Services" breite Unterstützung der ganzen Softwareindustrie fand. Demnach wird es zukünftig für verteilte Anwendungen auf der Microsoft-Plattform keine binären Kommunikationsprotokolle mehr geben, sondern nur noch das Simple Object Access Protocol (Soap). Als Interface Definition Language (IDL) dient die ebenfalls XML-gestützte Web Services Description Language (WSDL), derartige Dienstbeschreibungen lassen sich bei Bedarf über die Universal Description, Discovery and Integration (UDDI) auffinden.

Bruch mit der Tradition

Die unklaren Marketing-Botschaften des Desktop-Monopolisten verdeckten häufig die Tatsache, dass mit .NET eine radikale Abkehr von bisherigen Windows-Konzepten bevorsteht. Dieser Bruch wurde sowohl wegen immanenter Probleme der Microsoft-Plattform als auch durch die Anforderungen des Internet nötig - das Windows-Modell in der bisherigen Form bot kaum noch Erfolg versprechende Entwicklungsmöglichkeiten. Dass sich die Gates-Company dabei weitgehend an Java-Konzepte hielt, ist keine Überraschung. Die im Vergleich zu Windows junge Sun-Technologie wurde bereits im Internet-Zeitalter entworfen und vermeidet viele der Sicherheitsrisiken, die das klassische Desktop-Modell birgt. Aber auch sonstige Innovationen, die Java mit sich brachte, stehen Windows gut zu Gesicht, vor allem die durchgängige Objektorientierung inklusive der Möglichkeit, die Funktionalität von binären Objekten mittels Vererbung in den eigenen Programmen zu erweitern.

Natürlich liegt es nahe, .NET als bloßen Clone von Java abzuqualifizieren, wie es dessen Erfinder James Gosling auf der diesjährigen Java One tat (er bezeichnete es als "rip off"). Diese Kritik übersieht jedoch die erheblichen Innovationen, die .NET gegenüber Java auszeichnen und die Sun unter Zugzwang setzen werden. Dazu zählen die Nutzung von Web-Services als native Architektur von verteilten Anwendungen, reichhaltigere Metadaten mittels Attributen in den Quelltexten, eine ausgefeilte Versionsverwaltung und vor allem die Unterstützung für beliebig viele Sprachen. Letztere gilt allerdings mit gewissen Einschränkungen, weil eine moderne Anwendungsumgebung wie .NET einige Anforderungen an Programmiersprachen macht, zum Beispiel Objektorientierung und eine zeitgemäße Fehlerbehandlung. Deshalb wurde nicht ohne Murren der Visual-Basic-Gemeinde die .NET-Ausführung um Vererbung und Exception Handling erweitert. Letztlich gleichen sich die Sprachen unter .NET stark aneinander an, Visual Basic unterscheidet sich von C# im Wesentlichen nur mehr durch die Syntax (siehe dazu David Platt: Introducing Microsoft .NET, Seite 48, erschienen bei Microsoft Press).

Portierung dank Normierung

Java und .NET weichen zudem im Design ihrer Programmier-Schnittstellen voneinander ab: Während die Sun-Ingenieure vor allem auf Portabilität bedacht waren, ging es Microsoft darum, das Win32-API möglichst gut abzubilden. Auch wenn die Gates-Company die Common Language Infrastructure zur Standardisierung bei dem Normierungsgremium European Computer Manufacturers Association (ECMA) einreichte, muss sich erst zeigen, ob die Portierung auf andere Plattformen aus diesem Grund ohne größere Schwierigkeiten erfolgen kann - Microsoft selbst plant ein solches Vorhaben wohl nicht. Die Company betont statt der Portabilität stärker die Möglichkeiten der Interoperabilität mit anderen Systemen, die sich dank der nativ umgesetzten Web-Services-Architektur ergeben. In dieser Hinsicht weisen Java-Applikations-Server derzeit noch Defizite auf, weil Hersteller erst mit J2EE 1.3 das Internet Inter-ORB-Protocol (IIOP) als Standardprotokoll anbieten müssen.

Auch wenn Microsoft-Verantwortliche in ihrer Begeisterung für .NET die alte Anwendungsumgebung samt zugehörigen Programmen lieber heute als morgen loswerden wollen, so dürfte Erstere so bald nicht verschwinden. Da eine Ausführungsumgebung wie .NET oder Java aufgrund ihrer weit umfangreicheren Dienste zwangsläufig Geschwindigkeitsnachteile im Vergleich zu nativem Code nach sich zieht, werden Microsofts Back-Office-Server trotz .NET-Benennung vorerst wohl reine Windows-Anwendungen bleiben. Im Vergleich zu Java hat .NET indes den Vorteil, dass die Einführung des Systems durch die mittlerweile stark gestiegene Leistungsfähigkeit von PCs begünstigt wird. Dennoch dürfte die neue Anwendungsplattform aus Redmond für einen Update-Schub bei Hardware sorgen. Dafür stellt .NET Anwendern robustere Programme und mehr Sicherheit in Aussicht. Nicht zuletzt baut Microsoft damit einer weiteren Umstellung vor: .NET-Programme lassen sich ohne Anpassungen auf ein 64-Bit-Windows übernehmen, nur die Ablaufumgebung muss auf das neue System portiert werden.

Klartext statt binär

Auch mit der Nutzung von Klartextprotokollen wie Soap für verteilte Anwendungen vollzieht Microsoft eine Abkehr von alten Gewohnheiten: Die Erfindung immer neuer proprietärer binärer Datenstrukturen diente in der Vergangenheit dazu, Anwender an die hauseigenen Produkte zu ketten. Das Unix-Konzept sah demgegenüber immer vor, möglichst Textformate für Daten zu verwenden, um die Standard-Tools des Systems zu ihrer Bearbeitung heranziehen zu können (siehe dazu den Klassiker "Der Unix-Werkzeugkasten" von Kernighan und Pike, Seite 50: "Wenn Sie ein Dateiformat entwerfen, sollten Sie sorgfältig darüber nachdenken, bevor Sie nicht-textuell darstellen"). Auch die Installation von Programmen ohne Eingriffe in das System und die Konfiguration mittels menschenlesbarer Dateien folgen dem Unix-Vorbild.

Selbstbeschreibend

Aufgrund der Unterstützung für mehrere Sprachen können Visual-Basic- und C#-Entwickler gemeinsam an .NET-Projekten arbeiten. Heraus kommen dabei Programme, die als so genannte Assemblies ausgeliefert werden. Es handelt sich dabei um eine Sammlung logisch zusammengehöriger EXE- und DLL-Dateien, die sowohl den Programmcode in Form von MIL als auch umfangreiche Metadaten enthalten. Letztere geben etwa Auskunft über die Abhängigkeiten einer Datei, also welche DLLs sie zu ihrer Ausführung benötigt. Hinzu kommen unter anderem Informationen zur Versionsverwaltung, die unterstützte Landessprache, der öffentliche Schlüssel des Herstellers oder ob bestimmte Funktionen nach außen sichtbar sein sollen. Auf der Ebene der Quellcodes fügen Entwickler diese Daten in Form von Attributen ein. Da diese reichhaltigen Metadaten nicht mehr wie bei COM in Form von Type Libraries in der Registrierdatenbank hinterlegt werden, sondern Teil der Assembly sind, bezeichnet Microsoft .NET-Programme als selbstbeschreibend.