Javas drei Arten der Portabilität

Java hat in der Programmier-Community viel Aufregung ausgelöst, da es tragbare Anwendungen und Applets verspricht . Tatsächlich bietet Java drei verschiedene Arten der Portabilität: Quellcode-Portabilität, Portabilität der CPU-Architektur und OS / GUI-Portabilität. Die Tatsache, dass es drei verschiedene Arten von Portabilität gibt, ist entscheidend, da nur einer dieser Typen eine Bedrohung für Microsoft darstellt. Es ist zu erwarten, dass Microsoft diese eine Art von Portabilität untergräbt, während es die anderen beiden umfasst - und gleichzeitig behauptet, Java zu unterstützen. Das Verständnis der drei Arten der Portabilität und ihrer Zusammenarbeit ist entscheidend für das Verständnis der Bedrohung für Microsoft und der möglichen Reaktionen von Microsoft.

Bevor wir jedoch auf die Details dieser drei Arten der Portabilität eingehen, wollen wir einige grundlegende Begriffe betrachten.

Einige Begriffe definieren

Die folgenden Begriffe werden in diesem Artikel verwendet:

Endianismus
Endianismus bezieht sich auf die Speicherreihenfolge von Bytes in einer Multibyte-Menge in einer gegebenen CPU. Zum Beispiel benötigt der vorzeichenlose Kurzschluss 256 (dezimal) zwei Bytes Speicher: 0x01 und 0x00. Diese beiden Bytes können in der folgenden Reihenfolge gespeichert werden: 0x01, 0x00oder 0x00, 0x01. Der Endianismus bestimmt die Reihenfolge, in der die beiden Bytes gespeichert werden. Aus praktischen Gründen ist Endianismus normalerweise nur dann von Bedeutung, wenn CPUs mit unterschiedlichem Endianismus Daten gemeinsam nutzen müssen.
Java
Java besteht aus mehreren verschiedenen Technologien, die zusammen gepackt sind - der Java-Programmiersprache, der Java Virtual Machine (JVM) und den der Sprache zugeordneten Klassenbibliotheken. Dieser Artikel beschreibt all diese Aspekte.
Java Virtual Machine (JVM)

Die JVM ist eine imaginäre CPU, für die die meisten Java-Compiler Code ausgeben. Durch die Unterstützung dieser imaginären CPU können Java-Programme ausgeführt werden, ohne auf verschiedenen CPUs neu kompiliert zu werden. Nichts in der Programmiersprache Java erfordert, dass Java-Quellcode in Code für die JVM kompiliert wird, anstatt in nativen Objektcode.

Tatsächlich haben Asymetrix und Microsoft Java-Compiler angekündigt, die native Microsoft Windows-Anwendungen ausgeben. (Weitere Informationen finden Sie im Abschnitt Ressourcen dieses Artikels.)

J-Code
J-Code ist die Ausgabe, die von den meisten Java-Compilern in die Klassendateien ausgegeben wird. J-Code kann als Objektcode für die virtuelle Java-Maschine betrachtet werden.
Portabilität
Portabilität bezieht sich auf die Fähigkeit, ein Programm auf verschiedenen Computern auszuführen. Das Ausführen eines bestimmten Programms auf verschiedenen Computern kann unterschiedliche Arbeitsmengen erfordern (z. B. keinerlei Arbeit, Neukompilieren oder Vornehmen kleiner Änderungen am Quellcode). Wenn Benutzer Java-Anwendungen und -Applets als portabel bezeichnen, bedeutet dies normalerweise, dass die Anwendungen und Applets auf verschiedenen Maschinentypen ohne Änderungen ausgeführt werden (z. B. Neukompilierung oder Optimierung des Quellcodes).

Nachdem wir einige wichtige Begriffe behandelt haben, werden wir jede der drei Arten der Java-Portabilität erläutern.

Java als Sprache: Quellcode-Portabilität

Als Programmiersprache bietet Java die einfachste und bekannteste Form der Portabilität - die Portabilität des Quellcodes. Ein bestimmtes Java-Programm sollteunabhängig von der zugrunde liegenden CPU, dem Betriebssystem oder dem Java-Compiler identische Ergebnisse erzielen. Diese Idee ist nicht neu; Sprachen wie C und C ++ bieten seit vielen Jahren die Möglichkeit für diese Portabilität. C und C ++ bieten jedoch auch zahlreiche Möglichkeiten, nicht portierbaren Code zu erstellen. Sofern in C und C ++ geschriebene Programme nicht von Anfang an portabel sind, ist die Möglichkeit, auf verschiedene Maschinen zu wechseln, eher theoretisch als praktisch. C und C ++ lassen undefinierte Details wie die Größe und den Endianismus atomarer Datentypen, das Verhalten der Gleitkomma-Mathematik, den Wert nicht initialisierter Variablen und das Verhalten beim Zugriff auf freigegebenen Speicher.

Kurz gesagt, obwohl die Syntax von C und C ++ gut definiert ist, ist die Semantik dies nicht. Diese semantische Lockerheit ermöglicht es einem einzelnen Block von C- oder C ++ - Quellcode, in Programme zu kompilieren, die unterschiedliche Ergebnisse liefern, wenn sie auf verschiedenen CPUs, Betriebssystemen, Compilern und sogar auf einer einzelnen Compiler / CPU / OS-Kombination ausgeführt werden, abhängig von verschiedenen Compilereinstellungen. (In der Seitenleiste Syntax versus Semantik finden Sie eine Erläuterung der Unterschiede zwischen Semantik und Syntax.)

Java ist anders. Java bietet eine viel strengere Semantik und überlässt weniger dem Implementierer. Im Gegensatz zu C und C ++ hat Java Größen und Endianismus für die Atomtypen sowie ein definiertes Gleitkommaverhalten definiert.

Darüber hinaus definiert Java mehr Verhalten als C und C ++. In Java wird der Speicher erst freigegeben, wenn nicht mehr auf ihn zugegriffen werden kann und die Sprache keine nicht initialisierten Variablen enthält. All diese Funktionen tragen dazu bei, die Unterschiede im Verhalten eines Java-Programms von Plattform zu Plattform und von Implementierung zu Implementierung einzugrenzen. Auch ohne die JVM kann erwartet werden, dass in der Java-Sprache geschriebene Programme (nach dem Neukompilieren) viel besser auf verschiedene CPUs und Betriebssysteme portieren als gleichwertige C- oder C ++ - Programme.

Leider haben die Funktionen, die Java so portabel machen, einen Nachteil. Java geht von einer 32-Bit-Maschine mit 8-Bit-Bytes und IEEE754-Gleitkomma-Mathematik aus. Maschinen, die nicht zu diesem Modell passen, einschließlich 8-Bit-Mikrocontroller und Cray-Supercomputer, können Java nicht effizient ausführen. Aus diesem Grund sollten wir erwarten, dass C und C ++ auf mehr Plattformen als der Java-Sprache verwendet werden. Wir sollten auch erwarten, dass Java-Programme einfacher als C oder C ++ zwischen den Plattformen portieren, die beide unterstützen.

Java als virtuelle Maschine: CPU-Portabilität

Die meisten Compiler erzeugen Objektcode, der auf einer CPU-Familie ausgeführt wird (z. B. der Intel x86-Familie). Selbst Compiler, die Objektcode für mehrere verschiedene CPU-Familien (z. B. x86, MIPS und SPARC) erzeugen, erzeugen jeweils nur Objektcode für jeweils einen CPU-Typ. Wenn Sie Objektcode für drei verschiedene CPU-Familien benötigen, müssen Sie Ihren Quellcode dreimal kompilieren.

Die aktuellen Java-Compiler sind unterschiedlich. Anstatt eine Ausgabe für jede unterschiedliche CPU-Familie zu erzeugen, auf der das Java-Programm ausgeführt werden soll, erzeugen die aktuellen Java-Compiler Objektcode (J-Code genannt) für eine CPU, die noch nicht vorhanden ist.

(Sun hat eine CPU angekündigt, die J-Code direkt ausführt, gibt jedoch an, dass die ersten Beispiele für Java-Chips erst in der zweiten Hälfte dieses Jahres erscheinen werden. Die vollständige Produktion solcher Chips wird im nächsten Jahr beginnen. Die picoJavaI-Kerntechnologie von Sun Microelectronics wird das Herzstück der eigenen microJava-Prozessorlinie von Sun sein, die auf Netzwerkcomputer abzielt. Lizenznehmer wie LG Semicon, Toshiba Corp. und Rockwell Collins Inc. planen ebenfalls die Herstellung von Java-Chips auf Basis des picoJavaI-Kerns.)

Für jede reale CPU, auf der Java-Programme ausgeführt werden sollen, "führt" ein Java-Interpreter oder eine virtuelle Maschine den J-Code aus. Mit dieser nicht vorhandenen CPU kann derselbe Objektcode auf jeder CPU ausgeführt werden, für die ein Java-Interpreter vorhanden ist.

Das Produzieren von Ausgaben für eine imaginäre CPU ist mit Java nicht neu: Die Pascal-Compiler der UCSD (Universität von Kalifornien in San Diego) haben vor Jahren P-Code produziert. Limbo, eine neue Programmiersprache, die bei Lucent Technologies entwickelt wird, erzeugt Objektcode für eine imaginäre CPU. und Perl erstellt eine Zwischenprogrammdarstellung und führt diese Zwischendarstellung aus, anstatt nativen ausführbaren Code zu erstellen. Die internetaffine JVM unterscheidet sich von diesen anderen virtuellen CPU-Implementierungen dadurch, dass sie absichtlich so konzipiert wurde, dass nachweislich sicherer, virenfreier Code generiert werden kann. Vor dem Internet waren virtuelle Maschinen nicht erforderlich, um Programme als sicher und virenfrei zu beweisen. Diese Sicherheitsfunktion, kombiniert mit einem viel besseren Verständnis dafür, wie Programme für imaginäre CPUs schnell ausgeführt werden können, hat zu schnellen,breite Akzeptanz der JVM. Heutzutage haben die meisten wichtigen Betriebssysteme, einschließlich OS / 2, MacOS, Windows 95 / NT und Novell Netware, entweder integrierte Unterstützung für J-Code-Programme oder werden diese voraussichtlich haben.

Die JVM ist im Wesentlichen eine imaginäre CPU und unabhängig von der Quellcode-Sprache. Die Java-Sprache kann J-Code erzeugen. Ada95 auch. Tatsächlich wurden von J-Code gehostete Dolmetscher für mehrere Sprachen geschrieben, darunter BASIC, Forth, Lisp und Scheme, und es ist fast sicher, dass Implementierungen anderer Sprachen in Zukunft J-Code ausgeben werden. Sobald der Quellcode in J-Code konvertiert wurde, kann der Java-Interpreter nicht erkennen, welche Programmiersprache den von ihm ausgeführten J-Code erstellt hat. Das Ergebnis: Portabilität zwischen verschiedenen CPUs.

Das Kompilieren von Programmen (in jeder Sprache) zu J-Code hat den Vorteil, dass derselbe Code auf verschiedenen CPU-Familien ausgeführt wird. Der Nachteil ist, dass J-Code nicht so schnell läuft wie nativer Code. Für die meisten Anwendungen spielt dies keine Rolle, aber für die höchsten High-End-Programme - diejenigen, die jedes letzte Prozent der CPU benötigen - sind die Leistungskosten von J-Code nicht akzeptabel.

Java als virtuelles Betriebssystem und GUI: Portabilität des Betriebssystems

Die meisten in C oder C ++ geschriebenen Microsoft Windows-Programme lassen sich auch nach dem Neukompilieren nicht problemlos auf Macintosh- oder Unix-Umgebungen portieren. Selbst wenn die Programmierer besonders darauf achten, mit den semantischen Schwächen in C oder C ++ umzugehen, ist der Port schwierig. Diese Schwierigkeit tritt auch dann auf, wenn der Port zum Nicht-Windows-Betriebssystem ohne CPU-Wechsel erfolgt. Warum die Schwierigkeit?

Nach der Beseitigung der semantischen Probleme in C und C ++ und der CPU-Portierungsprobleme müssen sich Programmierer weiterhin mit dem unterschiedlichen Betriebssystem und den verschiedenen GUI-API-Aufrufen befassen.

Windows-Programme rufen das Betriebssystem ganz anders auf als Macintosh- und Unix-Programme. Diese Aufrufe sind für das Schreiben nicht trivialer Programme von entscheidender Bedeutung. Bis dieses Portabilitätsproblem behoben ist, bleibt die Portierung schwierig.

(Enthielt in Java gelieferten Bibliotheken wie Java löst dieses Problem , indem sie eine Reihe von Bibliotheksfunktionen bereitstellt awt, utilund lang) , dass die Rede auf ein imaginäres O und imaginäre GUI. So wie die JVM eine virtuelle CPU präsentiert, präsentieren die Java-Bibliotheken ein virtuelles Betriebssystem / eine virtuelle GUI. Jede Java-Implementierung bietet Bibliotheken, die dieses virtuelle Betriebssystem / diese virtuelle Benutzeroberfläche implementieren. Java-Programme, die diese Bibliotheken verwenden, um den erforderlichen Betriebssystem- und GUI-Funktionsport bereitzustellen, sind recht einfach.

Die Verwendung einer Portabilitätsbibliothek anstelle nativer OS / GUI-Aufrufe ist keine neue Idee. Produkte wie das Galaxy von Visix Software und das Zink von Protools Software bieten diese Funktion für C und C ++. Ein anderer Ansatz, dem Java nicht folgt, besteht darin, ein einzelnes OS / GUI als Master auszuwählen und Wrapper-Bibliotheken bereitzustellen, die dieses Master-OS / GUI auf allen Computern unterstützen, auf die Sie portieren möchten. Das Problem beim Master-OS / GUI-Ansatz besteht darin, dass die portierten Anwendungen auf den anderen Computern häufig fremd aussehen. Macintosh-Benutzer haben sich beispielsweise über eine aktuelle Version von Microsoft Word für Macintosh beschwert, da diese wie ein Windows-Programm aussah und sich nicht wie ein Macintosh-Programm verhält. Leider hat der Ansatz von Java auch Probleme.

Java hat in seinen OS / GUI-Bibliotheken eine Funktionalität mit dem kleinsten gemeinsamen Nenner bereitgestellt. Funktionen, die nur auf einem Betriebssystem / einer grafischen Benutzeroberfläche verfügbar sind, z. B. Dialogfelder mit Registerkarten, wurden weggelassen. Der Vorteil dieses Ansatzes besteht darin, dass die Zuordnung der allgemeinen Funktionen zum nativen Betriebssystem / zur nativen Benutzeroberfläche recht einfach ist und mit Sorgfalt Anwendungen bereitstellen kann, die auf den meisten Betriebssystemen / GUIs wie erwartet funktionieren. Der Nachteil ist, dass für Anwendungen im einheitlichen Modus Funktionen verfügbar sind, die für Java-Anwendungen nicht verfügbar sind. Manchmal können Entwickler dies umgehen, indem sie die AWT erweitern. andere Male werden sie nicht. In den Fällen, in denen die gewünschte Funktionalität mit Problemumgehungen nicht erreichbar ist, werden Entwickler höchstwahrscheinlich nicht portierbaren Code schreiben.

Wen interessiert die Portabilität?

Drei Hauptbereiche kümmern sich um die Portabilität: Entwickler, Endbenutzer und MIS-Abteilungen.

Entwickler: Chancen und Risiken sind groß

Entwickler haben ein begründetes Interesse daran, tragbare Software zu erstellen. Auf der anderen Seite können sie mit tragbarer Software mehr Plattformen unterstützen, was zu einer größeren Anzahl potenzieller Kunden führt. Die gleiche Portabilität, die es Entwicklern ermöglicht, neue Märkte anzusprechen, ermöglicht es Wettbewerbern jedoch auch, ihren Markt anzusprechen.

Kurz gesagt, die Java-Portabilität drängt den Markt für Anwendungssoftware von getrennten Märkten, die auf den verschiedenen Betriebssystemen und GUIs basieren, zu einem großen Markt. Auf dem aktuellen Softwaremarkt ist Microsoft beispielsweise eine Kraft, mit der man auf den Märkten für Windows- und Macintosh-Anwendungssoftware rechnen muss, auf den Märkten für OS / 2 und Unix jedoch kaum präsent. Diese Partitionierung ermöglicht es Unternehmen in den OS / 2- und Unix-Märkten, Microsoft als Konkurrenten zu ignorieren. Java erleichtert diesen Unternehmen den Wettbewerb auf dem Windows-Markt, ermöglicht Microsoft jedoch auch den Einstieg in die OS / 2- und Unix-Märkte.

Benutzer: Die indirekten Nutznießer der Portabilität

Benutzer kümmern sich nicht um die Portabilität an sich. Wenn Portabilität ihr Leben einfacher und angenehmer macht, dann sind sie alle dafür; wenn nicht, sind sie nicht. Die Portabilität hat einige positive Auswirkungen auf die Benutzer, diese sind jedoch etwas indirekt. Die positiven Effekte: