Ein Decompiler ist ein Computerprogramm, das aus Objekt- oder Maschinencodes einen erkennbaren Text in einer Hochsprache hervorbringt. So ist dieser Quelltext für den Menschen lesbar. Andere Bezeichnungen für den Decompiler sind Dekompilierer, Reverse Compiler oder Reverse Engineering Compiler. Beim Dekompilieren versucht das Programm, den Vorgang des Kompilierens rückgängig zu machen. Oft kommt es zu Verwechslungen zwischen Decompiler und Disassembler. Die Assemblersprache ist jedoch nur ein anderes Darstellungsformat des Maschinencodes.

Wie funktioniert ein Decompiler?

Für die Kompilierung gibt es häufig keine Wandlungsfunktion. Die Dekompilierung macht das mit der Reverse-Engineering-Technik möglich. Diese Technik erzeugt nachträglich einen Quellcode, der die Basis eines ausführbaren Programmes ist. Der wiederhergestellte Code ist dem Quellcode der ursprünglichen Fassung sehr ähnlich, der zur Bildung des durchführbaren Programmes angewendet wurde. Sind in dem Programm auch noch Debug-Informationen hinterlegt, dann sind die angewandten Funktionsnamen, Module und Variablennamen des ursprünglichen Autors erzeugbar. In der Regel gehen Formatierungen des Ursprungs sowie Kommentare verloren, weil diese Infos üblicherweise nicht im Kompilat einbezogen sind.

Das Dekompilieren von Bytecodes (zum Beispiel .NET- und Java-Programme) ist im Allgemeinen einfacher als das Dekompilieren von Maschinencodes. Das liegt daran, weil die Systeme eine Menge Informationen des basierten Quellcodes in die Objektdatei aufnehmen. Zu vergleichen ist das mit der Debug-Version eines C++- oder C-Programmes. Die Namen der öffentlichen Bezeichner sowie die Typinformationen bleiben bestehen. Die vom Decompiler erzeugten Programmcodes sind allerdings nur funktional deckungsgleich mit der Quelldatei des Ursprungs.

Welche Einschränkungen bestehen beim Dekompilieren?

Der hergestellte Quellcode kann in einzelnen Fällen bis zur Unbenutzbarkeit verzerrt sein. Das ist der Fall, wenn keine Debug-Informationen enthalten sind und das Programm mit einer Optimierungsoption des Compilers übersetzt wurde. Wegen dieser Einschränkung ist das Dekompilieren dem Grunde nach ungeeignet, um verlorene Quelltexte wieder aufzuarbeiten. Die Quelltexte sollten deshalb in mehreren Sicherungen zur Verfügung stehen.

Im allgemeinen Gebrauch setzt ein Programmierer eher selten einen Decompiler ein. Hin und wieder kann es vorkommen, dass bei sehr alten Softwareversionen die ursprünglichen Quellen nicht mehr vorhanden oder auf Datenträgern gespeichert sind, für die kein geeignetes Lesegerät mehr vorhanden ist. Zu Beginn des elektronischen Datenverarbeitens war es zudem geläufig, kleinere Fehler durch Patchen der Objektdateien zu beseitigen. Diese Fälle sind neben der Rückentwicklung einer fremden Software die alleinigen Anwendungsgebiete, für die das Dekompilieren zur Anwendung kommt.

Welche rechtlichen Bestimmungen sind beim Anwenden der Decompiler zu beachten?

Softwareanbieter verweisen häufig in den Lizenzen darauf, dass die Dekompilierung der Produkte untersagt ist. Das Verbot soll auch für das Verändern der Software für den eigenen Gebrauch sowie für Studienzwecke gelten. Dem steht allerdings eine gesetzliche Regelung entgegen (§ 69e Urheberrechtsgesetz), die unter gewissen Voraussetzungen gestattet, ein Programm zu dekompilieren. Der Einsatz eines Decompilers ist nach dieser Regelung erlaubt, um die Kompatibilität mit einem unabhängig vom Ursprungsprogramm geschaffenen Computerprogramm zu erreichen. Die gesetzliche Bestimmung weicht somit die Lizenzvereinbarungen auf und macht diese ungültig.

Was ist ein Compiler?

Programmiersprachen wie JavaScript, Python oder Java sind so aufgebaut, dass diese vom Programmierer ohne Weiteres zu schreiben und zu lesen sind. Damit der Computer mit den jeweiligen Programmbefehlen etwas ausführen kann, muss der Code zuerst in eine begreifliche Sprache umgewandelt werden. Je nach Plattform und Programmiersprache erfolgt das Umwandeln von einem Interpreter oder Compiler. Ein Compiler ist das Gegenteil vom Decompiler, denn der Compiler ist eine Software, die Quellcodes in Maschinensprache umgestaltet. Beim Kompilieren übersetzt die Software das ganze Programm von einer Programmiersprache in eine Maschinensprache. Bevor das Computerprogramm ausgeführt werden kann, wird der Code in seiner Gesamtheit übersetzt.

Was ist ein Betriebssystem?

Das System stellt die Verbindung zwischen der Hardware und den Anwendungsprogrammen her. Ein Betriebssystem trägt auch die Bezeichnung OS (Operating System). Für die Vermittlung der Zugriffe auf die Hardware-Ressourcen ist das Betriebssystem zuständig. Das können Festplatten, Arbeitsspeicher, Drucker sowie USB-Ports sein. Auch Smartphones und Tablets benötigen ein Betriebssystem. Die gängigsten Systeme sind Linux, Android, Windows, Unix, iOS und Mac OS.

 

Die Verwaltung und Kontrolle der Hardware übernimmt das jeweilige Betriebssystem des Computers. Dazu zählen auch Geräte wie das DVD-Laufwerk, die Tastatur, der Drucker, die Maus und anderweitige Hardware-Schnittstellen, zum Beispiel USB-Ports. Eine Anwendungssoftware (beispielsweise MS Word) kann diese Tätigkeiten auch eigenständig durchführen. In diesem Fall müsste jedoch das Programm für die unterschiedlichen Hardwareausführungen eigene MS-Word-Versionen vorhalten. Ein Betriebssystem reduziert den Aufwand für die Programme und schafft zudem eine konforme Oberfläche, auf die eine Drittanbietersoftware ansetzen kann.

Was ist ein Server?

Ins Deutsche übersetzt steht das Wort Server für Diener. Der Begriff wird in der Informatik doppeldeutig gebraucht. Ein Server bezeichnet zum einen den Computer, der Ressourcen über ein Netzwerk bereitstellt. Zum anderen beschreibt ein Server das Programm, welches auf dem Computer läuft.

  1. Server (Hardware):

Ein Server, der hardwarebasiert agiert, ist eine in ein Computernetz eingefasste physische Maschine. Auf dieser laufen neben dem Betriebssystem ein oder auch mehrere softwarebasierte Server. Eine andere Bezeichnung für einen Server, der auf Hardware basiert, ist Host.

 

  1. Server (Software):

Ein softwarebasierter Webserver ist ein Computerprogramm, welches einen speziellen Dienst zur Verfügung stellt. Dieser Dienst kann von anderen Programmen (= Clients) lokal oder über ein Netzwerk genutzt werden. Es ist abhängig von der Art der Server-Software, welcher Dienst verfügbar ist. Beim Austausch der Daten setzen dienstspezifische Übertragungsprotokolle ein.

 

 

 

Bei einer Programmiersprache handelt es sich um eine formale Sprache, mit denen sich Algorithmen und Datenstrukturen für den Computer formulieren lassen. Diese sogenannten Rechenvorschriften werden dann von einem Computer interpretiert und ausgeführt. Sie bestehen normalerweise aus schrittweisen Anweisungen aus erlaubten textuellen Befehlen und Strukturen, die mit dem Begriff Syntax bezeichnet werden. Während die ersten Programmiersprachen noch direkt an die Eigenschaften des jeweiligen Computers ausgerichtet waren, kommen heute vorwiegend Programmiersprachen höherer Ebenen zum Einsatz.

Die Funktionsweise einer Programmiersprache

Die Gesamtheit aller Befehle und Anweisungen, aus denen sich ein bestimmtes Computerprogramm zusammensetzt, wird als Quellcode bezeichnet. Der Quellcode eines Programms lässt sich in einem einfachen Texteditor erstellen, wie beispielsweise Notepad oder Sublime Text. Bei größeren Software-Projekten kommen allerdings sogenannte integrierte Entwicklungsumgebungen (IDE) zum Einsatz. Moderne IDEs, wie zum Beispiel Visual Studio oder Intellij IDEA, unterstützen den Entwickler bei seiner Programmiertätigkeit und tragen wesentlich dazu bei, die Produktivität des Entwicklers zu optimieren. Damit ein Computer die im Quelltext enthaltenen Befehle und Anweisungen verarbeiten und ausführen kann, muss der Quellcode zunächst in die Maschinensprache des jeweiligen Computersystems übersetzt werden. Dieser Vorgang wird als Kompilierung bezeichnet.

Die Maschinensprache ist ein Binärcode, der für Menschen nur schwer verständlich ist und primär an die Anforderungen und Bedürfnisse von Computersystemen ausgerichtet ist. Der Quellcode kann zu verschiedenen Zeitpunkten in die Maschinensprache kompiliert werden. Falls der Quellcode zur Laufzeit des Programms kompiliert wird, kommt ein sogenannter „Just-in-Time-Compiler“ oder Interpreter zum Einsatz. Bei einigen höheren Programmiersprachen, wie beispielsweise Java, wird eine Kombination aus traditioneller und der JiT-Kompilierung eingesetzt. So wird beispielsweise noch vor der Programmausführung der Java-Code in einen Zwischencode, den sogenannte „Bytecode“ überführt. Dieser wird dann während der Ausführung des Programms in Maschinencode übersetzt.

Die einzelnen Bestandteile einer Programmiersprache

Eine jede formale Programmiersprache lässt sich anhand verschiedener Merkmale näher definieren. Zu diesen Merkmalen gehören neben der Syntax auch der Zeichensatz und das Vokabular.

 

Syntax: Bei der Syntax einer Programmiersprache handelt es sich um deren „Grammatik“. Die Syntax gibt die zulässigen Sprachelemente explizit an. Außerdem definiert sie auch, wie diese Elemente zu verwenden sind.

Vokabular: Das Vokabular bezieht sich auf reservierte Schlüsselwörter, die nicht als Namen für Variablen, Klassen, Funktionen und Methoden gewählt werden dürfen.

Zeichensatz: Der Zeichensatz einer Programmiersprache setzt sich prinzipiell aus alphanumerischen und numerischen Zeichen und einigen Sonderzeichen zusammen.

 

Die Leistungsfähigkeit und der Umfang einer Programmiersprache hängen in erster Linie von der Mächtigkeit des Befehlssatzes ab. Moderne Programmiersprachen besitzen mindestens die folgenden Befehle:

– Befehle zur Deklaration von Variablen und anderen Datentypen und Datenstrukturen, wie beispielsweise Arrays, Klassen, Hashmaps, die bei der Zwischenspeicherung von Daten genutzt werden

– Befehle, die bei der Ein- und Ausgabe von Daten zum Einsatz kommen

– Mathematische Funktionen, wie beispielsweise Addition, Division oder Multiplikation

– Funktionen zur Verarbeitung von Strings (Zeichenkette)

– Bedingte Anweisungen und Verzweigungen, die bei der Implementierung von Programmlogik zum Einsatz kommen.

– Steueranweisungen und Schleifen für die wiederholte Ausführung bestimmter Programmteile

Aus der Kombination dieser Grundfunktionalitäten lassen sich komplexere Strukturen und Funktionen erstellen. Viele Programmiersprachen bieten außerdem die Möglichkeit, gängige Befehle als Funktionen höherer Ordnung in sogenannte „Bibliotheken“ zu bündeln und somit programmübergreifend wiederverwendbar zu machen.

Gängige Programmierparadigmen im Überblick

Die erste höhere Programmiersprache wurde in den USA im Jahr 1954 entwickelt. Der US-amerikanische Informatiker John Warner Backus war für den Entwurf der Programmiersprache Fortran zuständig, die heutzutage als die älteste sich noch im Gebrauch befindliche Programmiersprache gilt. Einige Zeit später im Jahr 1959 machte der Logiker John McCarthy die Programmiersprache LISP der breiten Öffentlichkeit zugänglich. Noch im selben Jahr wurde mit COBOL die erste Programmiersprache für kommerzielle Anwendungsbereiche vorgestellt. Im Laufe der Jahre kamen noch zahlreiche Programmiersprachen hinzu. Alle formalen Sprachen lassen sich in Klassen einteilen, die als Programmierparadigmen bezeichnet werden. Zu den bedeutendsten Programmierparadigmen gehören die prozedurale, die funktionale und die objektorientierte Programmierung.

  1. Prozedurale Programmierung: Hierbei handelt es sich um das älteste Programmierparadigma. Bei der prozeduralen Programmierung setzt sich ein Computerprogramm aus einer Reihe von Anweisungen und Befehlen zusammen, die nacheinander ausgeführt werden. Der Programmablauf wird durch bestimmte Kontrollkonstrukte, wie Verzweigungen oder Schleifen, gesteuert. Zu den Programmiersprachen, die dieses Paradigma unterstützen, gehören Sprachen wie Fortran, Go oder C.
  2. Funktionale Programmierung: Bei dem funktionalen Programmierparadigma setzt sich ein Computerprogramm aus einzelnen Funktionen zusammen, die untereinander zu Funktionen höherer Ordnung verknüpft werden. Seinen Ursprung hat die funktionale Programmierung in der wissenschaftlichen Forschung rund um das sogenannte „Lambda-Kalkül“, das eine formale, mathematische Sprache zur Untersuchung von Funktionen darstellt. Zu den beliebtesten Sprachen, die das funktionale Programmierparadigma unterstützen, gehören Programmiersprachen wie Haskell, JavaScript und LISP.
  3. Objektorientierte Programmierung: Bei dem objektorientierten Programmierparadigma stehen Objekt im Mittelpunkt. Bei objektorientierten Sprachen, wie Python, C++ oder Java bestehen Computerprogramme aus kooperierenden Objekten. Ein Objekt zeichnet sich dadurch aus, dass es einer bestimmten Klasse angehört, dass es Eigenschaften (Attribute) besitzt und verschiedene Handlungen (Methoden) ausführen kann. Einzelne Objekte sind außerdem in der Lage, Nachrichten an andere Objekte zu senden und zu empfangen.

Ein Computer ist nicht selbständig in der Lage, die Anweisungen, die ein Entwickler in Form von Programmcode schreibt, zu verstehen. Die Codebefehle müssen entweder von einem sogenannten Compiler in Maschinensprache übersetze werden oder von einem sogenannten Interpreter zur Laufzeit interpretiert werden. Im folgenden Artikel gehen wir auf das Thema Compiler im Detail ein und schauen uns die Besonderheiten dieser Technologie im Kontext anderen Techniken an.

Was ist ein Compiler?

Moderne Programmiersprachen wie Java, Python oder JavaScript sind so konzipiert, dass sie von Programmierern ohne größere Probleme gelesen und geschrieben werden können. Damit ein Computer/PC mit den einzelnen Befehlen eines Programms etwas anfangen kann, muss der Quellcode erst in eine für den Computer verständliche Sprache übersetzt werden. Je nach Programmiersprache und Plattform wird das beispielsweise von einem Compiler oder Interpreter realisiert. Bei einem Compiler handelt es sich um eine Software, die Quellcode in Maschinensprache umwandelt. Konkret bedeutet das, dass ein Compiler das gesamte Computerprogramm von einer Programmiersprache in Maschinensprache übersetzt. Dabei wird der Programmcode in seiner Ganzheit übersetzt, bevor das Programm auf dem Computer ausgeführt wird.

In vielen Fällen wird noch ein Zwischenschritt eingeleitet, bevor das Programm in Maschinencode umgewandelt wird. In diesem Schritt wird der Quellcode des Programms zunächst in einen sogenannten „Zwischencode“ übersetzt, wie beispielsweise Objektcode oder Bytecode. Der Zwischencode bietet den entscheidenden Vorteil, dass er in den meisten Fällen auf unterschiedlichen Plattformen ausgeführt werden kann, ohne neu kompiliert werden zu müssen. Außerdem kann er auch von einem Interpreter verarbeitet werden, was beispielsweise bei der Programmiersprache Java der Fall ist. Aus diesem Zwischencode übersetzt der Interpreter dann Maschinencode, der von der jeweiligen Zielplattform verstanden wird. Per Linker wird dann eine ausführbare Datei (EXE-Datei) erstellt. Programmiersprachen höherer Ebenen, wie zum Beispiel Java oder C# arbeiten häufig mit Objekt- bzw. Bytecode, während Programmiersprachen, die nähere an der Hardwareebene sind, ausschließlich mit Maschinencode arbeiten.

Im Rahmen der Kompilierung leitet der Compiler mehrere Schritte ein, um den jeweiligen Quellcode in ein lauffähiges Computerprogramm umzuwandeln. Je umfangreicher und komplizierter der Quellcode ist, umso mehr Zeit und Ressourcen werden bei der Kompilierung benötigt. Sobald das Programm jedoch lauffähig ist, kann es viel schneller und effizienter ausgeführt werden als interpretierte Programme. Dies ist auf die Tatsache zurückzuführen, da alle Anweisungen und Systemaufrufe bereits vollständig in einer für den Computer verständlichen Maschinensprache vorliegen. Beispiele für reine Compiler-Sprachen sind Pascal, C und C++.

Was ist ein Interpreter?

Bei einem Interpreter, wie beispielswiese bei der BASIC-Programmiersprache, handelt es sich um ein Computerprogramm, das den Quellcode einer Anwendung zur Laufzeit verarbeitet. Der Interpreter geht dabei Zeile für Zeile vor: Ein Befehlt wird erfasst, analysiert und sofort ausgeführt. Danach geht es mit dem nächsten Befehl weiter, bis das Ende des Quellcodes erreicht ist oder alternativ ein Fehler den Vorgang zum Stillstand bringt. Sobald etwas nicht stimmt, unterbricht der Interpreter seine Arbeit. Dies liefert Entwicklern wichtige Informationen zur Fehlerbehebung. Man weiß als Entwickler sofort an welcher Stelle im Quellcode sich der Fehler befindet und man kann das Problem so schneller beseitigen.

Im Gegensatz zum Compiler erzeugt ein Interpreter keine ausführbare Datei, die man verteilen, kopieren oder mehrmals ausführen kann. Außerdem fertigt er auch keine Umwandlung des Quellcodes in Maschinensprache an, sondern er fungiert viel mehr als eine Zwischenschicht zwischen der Programmiersprache und dem Computer. Ein Interpreter wertet zur Laufzeit jeden einzelnen Befehl eines Computerprogramms aus und ruft die entsprechenden Funktionen und Systemaufrufe auf, welche die gewünschten Funktionen auf dem Zielsystem auslösen. Da ein Interpreter in Echtzeit arbeitet, wobei jeder einzelne Befehl bearbeitet werden muss, sind interpretierte Sprachen, wie beispielsweise Python oder JavaScript, langsamer und weniger effizienter als kompilierte Sprachen. So werden beispielsweise auch wiederkehrende Anweisungen immer wieder aufs Neue aufgerufen, was die Effizienz äußerst negativ beeinflusst.

Das Beste aus beiden Welten: der Just-in-time Compiler

Heutzutage gibt es moderne Ansätze, die Interpreter und Compiler vereinen und so die Nachteile der jeweiligen Systeme eliminieren. Der Just-in-time-Compiler übersetzt den Quellcode erst zur Laufzeit in Maschinensprache. Die Kompilierung wird also nicht bereits vorab realisiert. Nachdem der Quellcode erfolgreich kompiliert wurde, wird er vom Prozessor des Zielsystems verarbeitet. Gegenüber der traditionellen Kompilierung hat diese Vorgehensweise wesentliche Performance-Vorteile. Bei der Just-in-time-Kompilierung werden gesamte Codeblöcke reihenweise bearbeitet. Auch das bringt gegenüber der sonst üblichen zeilenweisen Bearbeitung des Quellcodes eine Leistungssteigerung mit sich.

Moderne JiT-Compiler sind in der Lage, einen für dynamische Sprachen optimierte Code zu generieren. Darüber hinaus bietet die Just-in-time-Kompilierung den entscheidenden Vorteil, dass vor dem Programmstart nur ein geringer Teil kompiliert wird, wodurch das Problem der Verzögerung des Programmstarts so gut wie eliminiert wird. Darüber hinaus wird äußerst effizient mit den System-Ressourcen umgegangen. Codefragmente, die überhaupt nicht durchlaufen werden, werden auch nicht kompiliert. Im Rahmen der JiT-Kompilierung werden einmal fertig kompilierte Codeblöcke in einem Zwischenspeicher aufbewahrt. Bei einer erneuten Kompilierung werden die benötigten Codeblöcke einfach aus dem Zwischenspeicher geladen und müssen nicht neu kompiliert werden.

Solaris ist ein Betriebssystem auf Basis von SunOS und einem Unix-Betriebssystem, das für Benutzerfreundlichkeit, Sicherheit und Kompatibilität steht. Das Unternehmen Oracle hat sich mehr als 20 Jahre mit dem Entwickeln der Geschäftsplattform beschäftigt und Funktionen integriert, die dem neuesten Stand der Marktentwicklung entsprechen. Die Abwärtskompatibilität ist dabei beibehalten worden. Frühere und aktuelle Anwendungen werden durch die binäre Anwendungssicherheit in einer fortschrittlichen Infrastruktur ausgeführt. Solaris gehört seit der Übernahme von Sun Microsystems im Jahr 2010 zu dem Unternehmen Oracle. Doch was ist eigentlich ein Betriebssystem und wie arbeitet ein Webserver?

Betriebssystem

Ein Betriebssystem trägt auch den Namen OS und das stammt aus der englischen Bezeichnung operating system. Das System sorgt für den Zugang auf die Hardware-Ressourcen des PC, wie beispielsweise auf Drucker, USB-Ports, Arbeitsspeicher und Festplatten. Neben dem Computer brauchen auch Smartphones, Tablets und andere PCs ein Betriebssystem. Die bekanntesten Betriebssysteme sind Android, Unix, Linux, Mac OS, Windows und iOS.

Das Betriebssystem kontrolliert und leitet die Hardware (=Komponenten des PCs). Dazu zählen auch folgende Geräte: DVD-Laufwerk, Drucker, Maus, Tastatur und anderweitige Schnittstellen, wie zum Beispiel USB-Ports. Dem Grunde nach wäre eine Anwendungssoftware, wie beispielsweise MS Word, in der Lage, diese Aufgaben eigenständig zu bewerkstelligen. In diesem Fall müsste jedoch das Programm spezielle MS-Word-Versionen für die unterschiedlichen Hardwareausstattungen des PCs bereithalten. Ein Betriebssystem reduziert den verwaltungsrelevanten Aufwand für die Anwendungsprogramme. Des Weiteren besteht eine einheitliche Oberfläche, die es ermöglicht, dass eine Software von anderen Anbietern ansetzen kann.

Was ist ein Webserver?

Ein Webserver ist eine Software oder auch eine Hardware. Die Hardware ist für das Ausführen der Software vorgesehen und kann Inhalte für das Internet bereitstellen. Der Webserver bearbeitet die eintreffende Netzwerkanforderung über HTTP sowie weitere verwandte Protokolle. Eine Interaktion mit dem Webserver erfolgt immer dann, wenn man das World Wide Web nutzt, um Mails einzusehen, um auf eine Website zu kommen sowie um eine Verbindung zu sozialen Netzwerken herzustellen. Der Server ist dafür zuständig, alle Anfragen an eine Internetadresse zu beantworten.

Die wichtigste Funktion des Webservers ist das Speichern sowie Verarbeiten der Internetseiten und das Liefern an Clients. Die Verständigung zwischen Server und Client läuft über das Hypertext Transfer Protocol (HTTP). Internetseiten sind in der Regel HTML-Dokumente, die aus Textinhalten, Stylesheets, Skripts und Bildern bestehen können. Wenn die Website stark genutzt wird, dann kommen häufig mehrere Webserver zum Einsatz.

Details zu Solaris

Die Kompatibilität zur System-V-Familie besteht seit 1990. Alle Versionen davor wurden unter der Bezeichnung Unix xx Sun Version yy bereitgestellt. Die Benennung SunOS fand Anfang 1986 mit der ersten öffentlichen SunOS-3.0 Beta eine erstmalige Verwendung. Diese Version wurde auf der Grundlage von BSD-Unix für die Anwendung auf Workstations und Servern von Sun hervorgebracht. Der Name Solaris entstand, als die Version 5.0 von SunOS auf dem Ursprung von UNIX System V entwickelt wurde.

Funktionen und Besonderheiten von Solaris

Seit der Ausführung von Solaris 7 besteht eine durchgängige 64-Bit-Unterstützung auf UltraSPARC-CPUs. 1991 erfolgte die Ankündigung der Solaris-Portierung für x86, welche im Jahr 1992 an den Start ging. Die x86er-Prozessor-Version ist seit 1992 nutzbar. Diese Version bootet seit 2004 auch auf AMD64. Das ermöglichte in der Version 10 eine 64-Bit-Unterstützung für Intel-64-CPUs oder AMD64-CPUs. Die Version von Solaris für PowerPC wurde nach der ersten Version (Solaris 2.5.1) wieder stillgelegt. Eine neue Übertragung begann nach Herausgabe von OpenSolaris unter der Bezeichnung Polaris.

Seit 2005 besteht das OpenSolaris-Projekt unter der Führung von Sun. Das Projekt stellt den Solaris-Quellcode unter der Distribution License und der Common Development der Allgemeinheit zur Verfügung. Im Juni 2005 fand die Freigabe des Open-Source-Betriebssystems statt. Das erfolgte unter dem Namen OpenSolaris und beinhaltete Quellen für Kernel, Bibliotheken und einzelne Module. Im Zuge dessen sollte auch ein Solaris-Release für PowerPC starten. Zu Beginn des Jahres 2006 wurde von den Systementwicklern eine Übernahme auf die Pegasos-basierte CHRP-Workstation ODW von IBM/Freescale/Genesi bekanntgegeben, aber es ist nie ein Release daraus hervorgegangen.

Solaris und die Software

Die Verwaltung der Solaris-Software basiert vordergründig auf eine Paketverwaltung mithilfe der pkg-Programme (=pkgchk, pkgadd, pkgrm etc.). Es ist möglich, zahlreiche Programme auf Solaris zu portieren, welche auf Unix- und verwandten Betriebssystemen laufen. Das macht es realisierbar, tausende zusätzliche Software-Pakete für Solaris bereitzustellen. Die Softwarepakete können beispielsweise durch das OpenCSW-Projekt mit dem Programm pkgutil eingespielt werden. Durch  Weiterentwicklung der Solaris Observability-Tools können Anwendungs- und Systemfehler in Echtzeit behoben werden. Das ermöglicht einen Verlaufs- und Echtzeiteinblick und Probleme sind einfach und zügig zu erkennen und zu lösen.

Der Begriff Continuous Delivery (CD) ist englischen Ursprungs und bedeutet in die deutsche Sprache übersetzt so viel wie „fortwährende Lieferung“. Bei Continuous Delivery handelt es sich um ein Konzept aus dem Bereich der Softwareentwicklung, das sich in den letzten Jahren einer enormen Beliebtheit erfreut. Im folgenden Artikel gehen wir auf das Thema Continuous Delivery im Detail ein und beleuchten die speziellen Eigenschaften sowie die Vor- und Nachteile dieser innovativen Methode von allen Seiten.

Definition

Bei Continuous Delivery handelt es sich um ein Modell, das in der modernen Softwareentwicklung in Kombination mit DevOps immer beliebter wird und sich allmählich als Standard in der Softwarebranche etabliert. CD wird in der Softwareentwicklung eingesetzt, um Entwicklung, Bereitstellung, Feedback und Qualitätsmanagement in regelmäßigen kurzen Abständen ununterbrochen und parallel laufen zu lassen. Durch den Einsatz moderner CD-Methoden wird der gesamte Prozess der Entwicklung positiv beeinflusst und viel effizienter umgesetzt. So bekommt der Kunde beispielsweise das Produkt früher ausgeliefert, obwohl dieses noch nicht ganz fertig ist. Entwickler werden im Rahmen von Continuous Delivery kontinuierlich mit Feedback durch flächendeckende Tests versorgt, die nach jeder Änderung am Quellcode automatisch durchgeführt werden. CD beschreibt also einen dynamischen Prozess, der sämtliche Prozesse der Softwareentwicklung miteinander vereint und automatisiert. Dadurch lassen sich aufwendige und schwerfällige Arbeitsschritte minimieren. Continuous Delivery kommt in vielen bekannten Unternehmen zum Einsatz, wie beispielsweise Microsoft, Google und Red Hat.

Prinzipien und Praktiken der Continuous Delivery

Im Rahmen traditioneller Vorgehensweisen in der Softwareentwicklung wird das Endprodukt erst dann dem Kunden übergeben, wenn alle notwendigen Funktionen und Features implementiert sind, es ohne Probleme läuft und im Rahmen der Qualitätssicherung keine größeren Mängel gefunden wurden. Das Softwareprodukt wird dann anschließend von dem Entwickler mit regelmäßigen Patches und Aktualisierungen versorgt. Entwicklerteams, die auf moderne CD-Prozesse setzen, können die Software in einem viel früheren Entwicklungsstadium an den Kunden ausliefern, während das Produkt noch aktiv weiterentwickelt wird. Die ersten Versionen des Softwareprodukts enthalten in der Regel nur die Kernfunktionalitäten, die der Kunde in realer Umgebung testen kann. Der Kunde selbst nimmt keinen relevanten Platz im Rahmen der Qualitätssicherung ein.

Die auf diese Weise gewonnene Resonanz hilft dem Entwicklerteam, noch während der Entwicklungsphase vorhandene Funktionalitäten zu optimieren. Außerdem bekommt das zuständige Team wichtige Hinweise darüber, welche Funktionalität als nächstes implementiert werden sollte. Ohne Continuous Delivery sind diese einzelnen Schritte äußerst schwer zu implementieren und können sehr schnell zu Frust auf beiden Seiten führen. Der Kunde erwartet schließlich ein fertiges und funktionales Softwareprodukt, das seinen individuellen Wünschen und Anforderungen entspricht. Das Entwicklerteam weiß jedoch bis dahin überhaupt nicht, welche Anforderungen das überhaupt sind. Wenn die Kommunikation über den gesamten Entwicklungsprozess stattfindet, dann können Wünsche des Kunden viel schneller und präziser berücksichtigt und Unklarheiten vermieden werden.

Welche Vorteile bietet Continuous Delivery?

Continuous Delivery bringt mit anderen Methoden der modernen Softwareentwicklung, wie beispielsweise Continuous Integration und Continuos Deployment eine Vielzahl verschiedener Vorteile.

Automatisierung von Software-Einführungsprozessen: Durch den Einsatz der Continuous Delivery können Entwicklerteams Änderungen an der Codebasis automatisch erstellen und testen lassen sowie für die Produktionseinführung vorbereiten. Dadurch wird der Prozess der Software-Bereitstellung wesentlich schneller und effizienter gestaltet.

Steigerung der Entwicklerproduktivität: CI-Prinzipien und Praktiken steigern die Produktivität der Entwicklerteams, da sich Entwickler nicht mehr um manuelle Aufgaben kümmern müssen. Sie können sich stattdessen voll und ganz auf die Entwicklung, Bereitstellung und Optimierung des Produktes konzentrieren.

Bugs werden schneller entdeckt und behoben: Entwicklerteams sind in der Lage, Fehler (Bugs) im Softwareprodukt zu entdecken und zu beheben, noch bevor sie sich zu größeren Problemen entwickeln. Die Beseitigung von Bugs nimmt später nicht selten viel Zeit und Arbeitsstunden in Anspruch. Da der gesamte Entwicklungsprozess im Rahmen der Continuous Delivery automatisiert ist, können zusätzliche Tests der Codebasis schnell und einfach durchgeführt werden.

Schnellere Bereitstellung von Patches und Updates: Dank der CI-Praktiken können Entwicklerteams Updates und Patches für Kunden viel regelmäßiger und schneller bereitstellen.

Continuous Delivery Phasen

Bei jeder Änderung an der Codebasis wird die sogenannte „Continuous Delivery Pipeline“ gestartet und der Testprozess ausgeführt. Die Continuous Delivery Pipeline setzt sich dabei aus folgenden Phasen zusammen:

  1. Commit Stage: Die Commit Stage ist die erste Testphase. Hier werden die Software-Versionen validiert, die benötigten Software-Komponenten gebaut und notwendige Unit-Tests realisiert. Nachdem die Tests erfolgreich durchgeführt wurden, ist diese Phase abgeschlossen.
  2. Acceptance Test Stage: In der zweiten Testphase werden Akzeptanztests durchgeführt. Akzeptanztests setzen sich aus Systemtests (Wie gut funktioniert das Softwareprodukt auf der Seite des Nutzers) und Integrationstests (Wie ist das Zusammenspiel der einzelnen Softwarekomponenten) zusammen.
  3. Feedback und Fehlerbehebung: In dieser Phase werden auftretende Fehler protokolliert und als Feedback an das zuständige Entwicklerteam geschickt. Das kann beispielsweise über Messaging-Programme, E-Mail oder dedizierte Tools realisiert werden.
  4. Manuelle Prüfung: Je nach Bedarf werden in dieser Phase manuelle Tests realisiert.
  5. Installation auf dem Zielsystem: Sollten alle Tests mit positivem Feedback abgeschlossen sein, dann wird in dem letzten Schritt das Softwareprodukt auf dem Zielsystem manuell installiert. Um dies zu erledigen sind meist nur wenige Mausklicks notwendig. Wenn auch diese Phase automatisiert ist, dann spricht man von Continuous Deployment.

Schon seit Jahren gibt es Bestrebungen, diese Vielfalt konstruktiv zu vereinfachen und zu systematisieren. Write Once Run Anywhere bezeichnet einen Anspruch, der heute in ersten Fällen wirklich einlösbar geworden ist.

Virtualisierung als Grundlage von Write Once Run Anywhere

Hier betrachten wir hauptsächlich eine Virtualisierung eines Prozessors und eines Betriebssystems. Traditionell werden die in einer bestimmten höheren Programmiersprache geschriebenen Anweisungen interpretiert oder kompiliert in Befehle, die der Prozessor ausführen kann. Dasselbe gilt für das Betriebssystem, das System Calls bereitstellt, die von einem Anwenderprogramm aufgerufen werden können.

Virtualisierung bedeutet das Einziehen einer weiteren Schicht zwischen dem Anwenderprogramm und der Ausführung. Eine virtuelle Maschine bietet eine Menge von Befehlen und System Calls genau wie ein Prozessor mit einem Betriebssystem. Ein Anwenderprogramm wird in diesen Befehlssatz übersetzt und der virtuellen Maschine zur Ausführung übergeben. Jeder Befehl der virtuellen Maschine muss dann nochmals in Befehle des realen Prozessors übertragen werden.

Was bedeutet dann Write Once Run Anywhere hier? All dieser Aufwand muss schließlich einen Vorteil besitzen. Dieser liegt darin, dass nur die Übersetzung der Sprache der virtuellen Maschine in diejenige des Prozessors auf diesen Prozessor angepasst werden muss.

Die Virtualisierung der Programmiersprache Java

Hier ist es möglich, eine konkretere Antwort auf die Frage „Was bedeutet Write Once Run Anywhere?“ zu geben. Für Java wird auf den verschiedensten Plattformen eine JRE oder Java Laufzeitumgebung bereitgestellt. Diese entspricht einer virtuellen Maschine mit eigenen Funktionen, Befehlen und System Calls. Sie entspricht also in etwa einem eigenen Betriebssystem.

In Java entwickelte Software können Sie also auf allen diesen Plattformen laufen lassen, obwohl die Entwicklung nur einmal in der Sprache Java durchgeführt werden muss. Die technische Trennung bringt es auch mit sich, dass bei einem Absturz des Programms nur die JRE betroffen ist. Sie müssen also in einem solchen Fall nicht damit rechnen, dass der ganze Computer neu gestartet werden muss.

Probleme und Nachteile des „Write Once Run Anywhere“

– Die virtuelle Maschine nimmt eine bestimmte Rechenleistung in Anspruch. Diese steht dann für die Anwendungen nicht mehr zur Verfügung, was eine langsamere Ausführung zur Folge hat.

– Die Isolierung der realen Maschine durch die virtuelle ist aus den oben genannten Gründen gewollt, bringt aber auch nicht vermeidbare negative Konsequenzen mit sich. Die Speicherverwaltung ist nicht unter Ihrer direkten Kontrolle und das kann die Verarbeitungsgeschwindigkeit merklich beeinflussen. Deshalb wird die Verwendung von Java für Echtzeitsysteme mit zeitkritischen Anwendungen nicht empfohlen.

– Ihnen als Anwendungsentwickler stehen nur die von der JRE unterstützten Funktionen zur Verfügung. Der Prozessor Ihres Geräts mag noch weitere Befehle ausführen können, aber auf diese lässt sich durch die virtuelle Maschine nicht zugreifen. Das würde schließlich den Anspruch universeller Ausführbarkeit verletzen, da die entsprechenden Befehle eben nicht auf allen Prozessoren ausführbar sind.

Möglichkeiten der Umsetzung von Write Once Run Anywhere

Im Fall der JRE für Java wird der Anspruch der universellen Ausführbarkeit nur eingeschränkt erfüllt. Es können sich subtile Unterschiede zwischen der Ausführung eines für die JRE kompilierten Programms auf verschiedenen Plattformen ergeben. Auch die Gerätetreiber sind hinreichend unterschiedlich und auf die jeweiligen realen Geräte anzupassen, sodass die Ausführbarkeit nur eingeschränkt gegeben sein kann.

Schließlich sollten Sie auch bedenken, dass die Compiler und die Teile der JRE genauso wenig wie andere Software als fehlerfrei angesehen werden können. Durch verschiedene Fehler der JRE für unterschiedliche Plattformen ergibt sich ebenfalls unterschiedliches Laufzeitverhalten auf den entsprechenden Geräten.

Manche Programmierer haben deshalb die Erfahrung gemacht, dass die Antwort auf die Frage „Was bedeutet Write Once Run Anywhere?“ auch „Write once, debug everywhere“ lauten kann. Das Javaprogramm muss dann also auf den verschiedenen Plattformen zumindest getestet und gut möglicherweise auch korrigiert werden.

Es sollte auch bemerkt werden, dass dieselbe Software für verschiedene Plattformen auch einfach nicht wünschenswert sein kann, weil sie in einem solchen Fall keine Rücksicht auf unterschiedliche Erwartungen der Nutzer nehmen kann. So sind schon einfache Konventionen der grafischen Benutzeroberfläche verschieden wie etwa die Position der Buttons für das Speichern und Verwerfen von Änderungen an einer Datei. Wird ein solcher Unterschied nicht beachtet, kann das zu eingeschränkter Benutzerfreundlichkeit oder sogar zu Fehlern in der Benutzung führen.

Neue Antworten auf die Frage „Was bedeutet Write Once Run Anywhere?“

Ein neuer Zugang zu diesem Themenkreis ist der Dialekt Squeak der Programmiersprache Smalltalk. In diesem System wurde die universelle Ausführbarkeit im Wesentlichen komplett realisiert. Die strukturellen Einschränkungen dieses Zugangs kann aber auch Squeak logischerweise nicht vermeiden.