Eigene Collection-Klassen

Wer braucht eigene Collection-Klassen? Java, Perl, Ruby, Scala, Clojure, sie alle haben gute Bibliotheken und da sind sehr schöne Collection-Klassen verfügbar und wenn die mitgelieferten nicht reichen, findet man noch passendere. Es lohnt sich zu suchen.
Gelegentlich braucht man komplexere Collections, z.B. Mengen, die noch eine Gruppierung in disjunkte Teilmengen aufweisen und wahlweise über die einzelnen Teilmengen oder als Gesamtmenge angesprochen werden können. Man denke an die Menge aller Räume in einem Gebäude und die Teilmengen der Räume in einem bestimmten Stockwerk. So etwas läßt sich leicht aus den vorhandenen Strukturen zusammensetzen, man muss nur noch schauen, dass man das entsprechende Interface für die Gesamtmenge implementiert.

Es gibt aber durchaus auch Fälle, wo man aus Performance-Gründen wirklich dezidierte Collections für den Anwendungsfall braucht und weder im Lieferumfang noch im Netz in der erfordelichen Qualität findet. Da typische Collection-Klassen sehr allgemein und flexibel gehalten sind, kann man Annahmen treffen und nutzen und so einiges abkürzen. Nur als Beispiel ließ sich einmal in Java eine Map durch eine eigene Implementierung ersetzen, die für die Schlüssel vom Typ long optimiert war und wesentlich weniger Speicher verbrauchte, solange die gespeicherten Wert-Objekte relativ klein waren. Da dies eine große Applikation war, die auf Servern wirklich das Memory aufgebraucht hat und man noch in der Begrenzung der 32-Bit-Welt agieren musste, ließ sich dadurch das Problem des zu großen Speicherverbrauchs in den Griff bekommen. Voraussetzung war natürlich, dass diese Tabellen einen großen Teil des Speichers belegten.

Share Button

WLAN-Router

Aus Sicherheits- und Durchsatzgründen ist es immer noch eine gute Idee, ein Netzwerk mit Kabeln anzulegen. Da wir so arbeiten, dass das Home-Verzeichnis auf einem NFS-Server liegt und alle Dateien auf diesem Rechner gespeichert werden und außerdem X11-Applikationen gelegentlich auf anderen Rechnern mit umgeleitetem Display laufen, ist ein zuverlässiges und schnelles und sicheres lokales Netzwerk sehr wichtig. Die Verkabelung im Gebäude ist dafür eingebaut worden.

Aber ein WLAN-Netzwerk ist trotzdem sinnvoll. Inzwischen können fast alle Mobiltelefone damit umgehen und man kann z.B. mit Signal oder Threema oder Skype telefonieren und das auch Gästen zur Verfügung stellen. Da Mobiltelefone und andere Mobilgeräte, die WLAN können, sowieso an anderen Orten direkt und ohne Firewall im Internet sind, habe ich eine Firewall zwischen WLAN und dem Kabelnetz eingefügt. Witzigerweise bieten die üblichen WLAN-Router zwar eine rudimentäre Firewall-Funktionalität, aber nur gegenüber der Netzwerkverbindung nach außen, weil anscheinend kaum jemand das Kabelnetz und as WLAN trennen will. Das lässt sich alles lösen, weil man natürlich die Firmware des WLAN-Routers austauschen kann und wenn nicht einen kaufen kann, bei dem das geht. Letztlich erwies es sich aber als einfacher, eine dezidierte Firewall zu kaufen und dazwischen zu schalten.

Für das WLAN selbst ist nun die Verschlüsselung eigentlich nicht sonderlich wichtig, sie erschwert es nur Gästen, das Netz zu benutzen. Da ja alle Geräte, die das WLAN benutzen, auch gelegentlich öffentliche WLAN- oder Mobilnetze verwenden, ist es sowieso notwending, die Geräte genügend abzusichern oder deren normaler Konfiguration zu vertrauen.

Hierzu kann man auch bei Bruce Schneier lesen, warum er sein
WLAN offen hat.

Share Button

Akka-Framework

Die Idee ein Framework zu entwickeln, dass ganz auf Messages zur Kommunikation zwischen den Komponenten basiert, ist interessant. Ich habe schon verschiedene Ansätze in der Java-Welt gesehen, z.B. Versuche, das in JavaEE mit JMS zu bauen. Letztlich ist das in der Java- und JVM-Welt ein eher selten verwendeter Ansatz, aber z.B. Erlang-Software basiert komplett auf diesem Prinzip, wobei natürlich effiziente Messaging-Mechanismen vorausgesetzt werden müssen.

Das Akka-Toolkit oder Akka Framework setzt diese Idee nun in konsequenter Weise für die Java- und JVM-Welt um, wobei es natürlich am besten in seiner nativen Sprache, also in Scala verwendet wird. Die Idee ist, eine effiziente massive Parallelisierung hinzubekommen und durch assynchrone Kommunikation die Komponenten weitestgehend zu entkoppeln. Typisch in der Scala-Welt ist es, dass man unveränderliche (deep immutable) Objekte in den Messages verschickt, um Änderungskonflikte und Fehler zu vermeiden, wenn dasselbe Objekt an mehreren Orten gleichzeitig verwendet wird. Veränderbare Objekte in den Messages sollte man vermeiden, außer man kennt das Framework und die Multithreading-Thematik sehr gut und weiss was man tut und es ist aus Performance-Gründen wirklich ein so großer Vorteil, dass der zusätzliche Entwicklungs- und Testaufwand gerechtfertigt ist. Dabei ist noch zu sagen, dass sich solches Verhalten kaum testen lässt, weil das Zeitverhalten in den Tests nie genau das im ungünstigsten Fall auf dem Produktivsystem sporadisch auftretende Zeitverhalten ist. So können in schlecht oder fahrlässig programmierten Applikationen noch Fehler lauern, die erst irgendwann auf dem Produktivsystem auftreten und die sich dann noch schlecht einordnen lassen. Genau deshalb sollte man hier auf Nummer sicher gehen und nur deep-immutable Objekte in Messages verschicken.

Für die Parallelisierung von Software gibt es grundsätzlich verschiedenen Ansätze. Mehrere getrennte Prozesse sind attraktiv, weil die Trennung sauber ist und man nur bei der Kommunikation überhaupt aufpassen muss. Dafür sind sie etwas schwergewichtiger als Threads und vor allem ist der Aufwand für de Kommunikation größer. Mehrere Threads zu verwenden hat den Vorteil, dass man dasselbe Memory benutzt und deshalb Daten einfacher getauscht werden können. Dafür steigen auch die Risiken, wenn mehrere Zugriffe auf dasselbe Objekt gleichzeitig stattfinden und mindestens einer davon schreibend ist.

Akka verwendet sogenannte Aktoren (engl. Actors), die einen Memory-Footprint von unter 1 k haben sollen, weshalb man etwa eine Million Actors durchaus gleichzeitig im Memory haben kann. Nun werden diesen Actors Messages geschickt, die etwa Methodenaufrufen in der (synchronen) objektorientierten Denkweise entsprechen, aber assynchron sind. Das heißt, dass der Sender die Message verschickt und dann fertig ist. Sie wird in einer Warteschlange für den passenden Actor eingereih und dann irgendwann abgearbietet. Nun hat so ein Actor nicht permanent einen Thread zugewiesen, sondern es gibt einen Threadpool. Actors mit einer nicht-leeren Warteschlange werden dann einem Thread im Threadpool zugewiesen und so abgearbeitet.

Share Button

Telearbeit

Durch die heutigen Möglichkeiten wie VPN, Mobiltelefonie, Videotelefonie, Chat, Telefon, EMail, Zugriff auf Fileserver u.s.w. kann man neuerdings von zuhause aus arbeiten. Wenn man die Sache genauer anschaut, ist natürlich das bezahlbare Festnetztelefon, das es schon eine Weile gibt, schon für viele Tätigkeiten schon völlig ausreichend und auch das Internet gab es schon vor 20 Jahren, als das alles noch einfacher ging, weil noch kaum jemand an Firewalls dachte, die einem das Leben für den Zugriff von außen erschweren könnten. Aber natürlich hat man heute noch mehr Möglichkeiten und hat auch 20 Jahre Zeit gehabt, darüber nachzudenken. Attraktiv ist es ja, weil man dadurch Wege spart und die Umwelt schont. Manche Firmen verzichten sogar auf einen festen individuellen Büroarbeitsplatz und lassen die Mitarbeiter 20% der Zeit von zuhause arbeiten, um Kosten zu sparen. Gerade Informatikberufe eignen sich dafür.

In der Praxis zeigt es sich, dass es oft sinnvoll ist, jeweils an dem Ort zu arbeiten, der für die aktuelle Tätigkeit am effizientesten ist. Das ist meistens der Ort, wo die Leute sind, mit denen man zusammenarbeitet, weil einfach die direkte Kommunikation immer noch viel besser funktioniert als über elektronische Medien. Es kann aber auch gerade ein Ort sein, der leiser ist als das Großraumbüro, in dem alle dauernd telefonieren oder Besprechungen am Arbeitsplatz durchführen. Es gibt auch recht viele Firmen, bei denen alle oder fast alle Mitarbeiter dauernd von zuhause aus arbeiten, wenn sie nicht gerade für die Firma unterwegs sind, z.B. für das alljährliche Mitarbeitertreffen. Solche Firmen sind dann über viele Länder verteilt und haben in jedem dieser Länder einen oder mehrere Mitarbeiter. Man sieht das häufig bei Open-Source-Firmen und mir sind viele Beispiele dafür bekannt.

Nun ist das verlockend, man kann sich die Wege sparen und sich sein Büro wirklich individuell einrichten. Aber es hat auch Nachteile. Solange die Arbeitswege nicht zu lang sind, ist es auch ein Luxus, nach Hause zu kommen und nicht mehr arbeiten zu müssen. Diese Grenze verschwimmt leicht einmal, wenn man oft zuhause arbeitet. Lohnt sich das? Die Frage kann man wohl nur individuell beantworten. Die zweite Frage, die ja niemand zu stellen wagt, ist ob denn da wirklich so intensiv gearbeitet wird. Es gibt Tätigkeiten, die von sich aus schon einen Rhythmus vorgeben oder bei denen das Ergebnis leicht messbar ist. Es gibt aber auch Tätigkeiten, die sich nicht so leicht fassen lassen. Da funktioniert diese Telearbeit gut, wenn sich die Mitarbeiter dem gemeinsamen Ziel verpflichtet fühlen und motiviert sind, ihren Teil dazu beizutragen. Man kann das durchaus lernen.

Wichtig ist an solchen Tagen, dass man auch innerhalb der eigenen Wohnung klare Abgrenzungen zwischen Arbeitszeit und Freizeit findet, auch um die Freizeit zu schützen. Ein fester Tagesablauf hilft dabei sicher und vielleicht ist es sogar gut, wenn man zwei verschiedene Rechner für die Arbeit und die Freizeit hat. Das haben in dem Fall die meisten, weil es einen Firmenlaptop und einen privaten Rechner gibt, die nur selten in einem Gerät vereinbar sind.

Hierzu ein paar andere Blogbeiträge und Artikel auf Englisch:

Share Button

iO hat zusätzliche Services

iO der Swisscom bietet jetzt die Möglichkeit, abhängig vom zugrundeliegenden Abo zusätzliche Möglichkeiten für jeweils einen Monat dazuzukaufen. Damit kann man aus der iO-App Nummern in der Schweiz oder mit dem passenden zugrundeliegenden Abo sogar Nummern aus bestimmten Ländenr in Europa und Nordamerika. Für diejenigen, die im Urlaub WLAN auf dem Zeltplatz oder Hotel zur Verfügung haben, kann das nützlich sein und Roaminggebühren sparen.

Update 2019-03-23: https://io.swisscom.ch/ ist nicht mehr erreichbar. iO gibt es auch seit über einem Jahr nicht mehr.

Share Button

Kovarianz und Kontravarianz

Bei Typsystemen objektorienter Programmiersprachen wird man gelegentlich mit Kovarianzu und Kontravarianz konfrontiert. Im Fall von Java stellt man sogar fest, dass bei Arrays hier ein konzepitioneller Fehler unterlaufen ist, den man heute nicht mehr wegbekommt.

Wenn man zum Beispiel die Vererbungshierarchie

Frucht -> Citrusfrucht -> Zitrone

hat, dann ist es intuitiv plausibel, anzunehmen, dass eine Liste von Citrusfrüchen sowieso immer auch eine Liste von Früchten ist. Das ist das Prinzip der Kovarianz. Wenn man mal in der Java-Welt das anschaut, dann kann eine Methode, die aus einer Liste Objekte entimmt und damit irgendwelche Berechnungen macht, durchaus gut damit leben, wenn statt der erwarteten List eine List kommt, denn was daraus gelesen wird, sind ja alles gleichzeitig auch Citrusfrüchte. Wenn diese Liste nun noch immutable ist, stimmt die Sache sogar. Dagegen würde eine List nicht funktionieren.

Nun wird es aber gefährlich, wenn die Methode dort Objekte hinzufügt. Das ist von den Sprachkonstrukten her durchaus möglich. Wenn aber nun Liste erwartet wird und stattdessen List übergeben wird und dort Orangen hinzugefügt werden, so ist das gegen die Idee einer Liste von Zitronen. Dagegen könnte man die Orangen sehr gut in eine List einfügen. Hier kommt das Prinzip der Kontravarianz zum Zuge.

Bei den Generics wurden Kovarianz und Kontravarianz einigermaßen richtig berücksichtigt, bei Arrays wurde aber nur die Kovarianz wahrgenommen, was wie erwähnt falsch ist.

In Scala sind diese Konzepte viel präziser und sauberer umgesetzt.

Siehe auch: Wikipedia

Share Button

Nokia steigt aus dem Mobiltelefongeschäft aus

Der Ausstieg fand eigentlich schon statt, als S. Elop dort die Leitung übernommen hat und den Marktanteil bei Smartphones innerhalb weniger Monate von etwa 50% auf knapp 3% reduziert hat.

Hier ein ein interessanter Artikel zu dem Thema:

Tech More: Microsoft Nokia Some People In The Finnish Tech Industry Are Pretty Upset About The Microsoft-Nokia Deal

Hier noch ein Beitrag, der am Erfolg des Deals für Microsoft zweifelt:

CIO.de

Wie es aussieht, werden sich einige neue Firmen in Finnland etablieren, die davon profitieren, dass viele hochqualifizierte Mitarbeiter bei Nokia entlassen wurden oder der Firma den Rücken gekehrt haben oder es jetzt tun werden. Mit Jolla gibt es sogar wieder einen kleinen, aber vielversprechenden Mobiltelefonhersteller.

Share Button

Alles Immutable: Wie geht das?

Ein radikaler Ansatz, um Multithreading zu vereinfachen, ist es „alles“ immutable zu machen. Man meint, dass das in Java schon recht gut der Fall ist, sind doch Objekte von grundlegenden Klassen wie String, Long, Integer, BigInteger, BigDecimal u.s.w. immutable. Date ist ein bisschen ein Spezialfall, da es fast immer verwendet wird, als wäre es immutable, was aber in Wirklichkeit nicht stimmt.

Aber die Collection-Klassen sind natürlich a priori fast alle mutable. Müssen sie ja sein, weil es z.B. keine vernünftige Schreibweise für eine Map gibt und man sie deshalb sukzessive aufbauen muss. Zwar gibt es die unmodifiable-Wrapper in Collections, aber wenn man Zugriff auf die eingebaute Collection hat, kann man diese immer noch ändern, was zu Überraschungen führen kann.

Die üblichen Collections in Clojure funktionieren anders. Sie sind wirklich immutable. Wenn man also so etwas ähnliches wie ein map.put(k, v) oder map[k]=v in Clojure macht, wird map selber nicht verändert, sondern es wird eine Kopie zurückgegeben, die zusätzlich das neue Paar enthält.

Hier ein Beispiel:

user=> (def x (hash-map 3 4 5 6))
#'user/x
user=> x
{3 4, 5 6}
user=> (def y (assoc x 7 8))
#'user/y
user=> y
{3 4, 5 6, 7 8}
user=> x
{3 4, 5 6}

Man kann sich vorstellen, dass da tatsächlich immer Kopien gemacht werden. Dann würde Clojure natürlich für größere Programme exorbitant Speicher verbrauchen und wäre auch sehr langsam.

Man muss sich eher vorstellen, dass ausgenutzt wird, dass auch die Eingaben immutable sind und dass geschickte interne Datenstrukturen sicherstellen, dass man das Verhalten bekommt, als wäre es kopiert worden, aber intern Optimierungen stattfinden, die mehrfach benutzte Daten gemeinsam nutzen.

Share Button

GNU-Emacs und Unicode

Heute sollte man Text-Dateien bevorzugt in Unicode erstellen und speichern. Natürlich braucht man nur englische Texte, deshalb reicht ISO-646 (ASCII) aus, aber ein paar Umlaute kommen doch noch rein, allein wegen Eigennamen und so kann man ISO-8859-1 oder ISO-8859-15 nehmen und hat die Umlaute auch dabei. Praktisch mit demselben Aufwand kann man stattdessen UTF-8 verwenden. Das erlaubt es, die Umlaute zu haben, aber auch alle anderen Unicode-Zeichen. Und die seltenen Umlaute sind zwei Bytes statt einem groß, was in aller Regel vernachlässigbar ist. Eine andere Frage ist es aber, wenn man z.B. Russisch, Griechisch, Japanisch oder Chinesisch schreibt. utf-8 führt dazu, dass die griechischen und russischen Buchstaben mindestens zwei Bytes brauchen und die chinesischen und japanischen noch mehr. Bei diesen Sprachen ist zugegebenermaßen der Anreiz, eine Codierung zu verwenden, die auf diese Sprache zugeschnitten ist, größer, weil man so die Textdateien um Faktor 1.5 oder 2 kleiner machen kann. Weiß jemand, wie das heute praktiziert wird? In welcher Codierung speichert man üblicherweise Textdateien bei Sprache, die nicht auf lateinischen Buchstaben basieren?

Nun hat GNU-Emacs leider vor vielen Jahren seine eigene Idee statt Unicode entwickeln wollen, wie man die Zeichen der verschiedenen Sprachen codiert. Wer das noch weiß, wird vielleicht dem ganzen Werkzeug misstrauen, aber das ist nicht nötig.
Man kann eine einzelne Datei als Textdatei in utf-8 markieren, indem man in der ersten Zeilen einen Kommentar hat, der etwa so aussieht:

// -*- coding: utf-8-with-signature-unix -*-
// -*- coding: utf-8-with-signature -*-
// -*- coding: utf-8-unix -*-
// -*- coding: utf-8 -*-

Ab dann wird die Datei als Unicode gespeichert und auch beim nächsten öffnen interpretiert.
Das „-unix“ erzwingt einen Zeilenwechsel nur aus „ctrl-J“ (LF), statt „ctrl-M ctrl-J“ (CR LF), was in der Regel besser funktioniert, wenn man sowohl auf Win64/Win32 als auch auf Linux/Unix-Plattformen unterwegs ist.
Das -with-signature führt dazu, dass am Anfang der Datei eine „Signatur“ aus drei Bytes eingefügt wird, die ausdrückt, dass die Datei utf-8 ist. Leider wird diese Signatur nicht von allen Werkzeugen verstanden, aber wenn sie verstanden wird, ist das eigentlich der richtige Ansatz, weil man so wirklich utf-8 erkennen kann, ohne die ganze Datei vorher zu lesen.

Das läßt sich auch pro Endung festlegen, wenn man in .emacs so etwas schreibt:

(defvar utf8-suffix-regex nil "describes suffixes of files that are always utf8")

(setq utf8-suffix-regex "\\.\\(cs\\|scala\\|java\\|groovy\\)$")

(defun choose-encoding-by-suffix ()
  "Choose the encoding based on suffix"
  (interactive)
  (when (and (stringp buffer-file-name)
             (string-match utf8-suffix-regex buffer-file-name))
    (set-buffer-file-coding-system 'utf-8-unix nil t)))

(add-hook 'find-file-hook 'choose-encoding-by-suffix)

Wenn bei diesen impliziten Konvertierungen etwas schiefgeht, z.B. weil iso-8859-1 nach utf-8-Konvertierung zweimal statt einmal gelaufen ist, dann hilft recode. Man kann im Emacs die geöffnete Datei mit recode konvertieren:
Ctrl-X h ESC 1 ESC | recode utf8..latin1
Es empfiehlt sich, vorher eine Sicherungskopie anzulegen.

Dieselben Fragestellungen tauchen mit anderen Editoren und Entwicklungsumgebungen auch auf. In Eclipse und Netbeans kann man die Codierung von Dateien nach Endung, Projekt und auch für einzelne Dateien festlegen. Sicher wissen die vi-Spezialisten gut Bescheid, wie es mit vi geht.

Entscheidend ist, dass man sich bewusst für eine Codierung entscheidet. In Sprachen mit lateinischer Schrift dürfte das fast immer utf-8 sein, wenn man nicht „Altlasten“ hat. Das lässt sich mit geeigneten Editoren in den Griff bekommen.

Links

Share Button

Einmal entwickeln – überall installieren

Das ist eine der großen Versprechungen von Java gewesen. Nun gab es drei oder bei genauerem Hinschauen etwas mehr als drei Varianten von Java, also „Micro-Edition“ (JavaME) für Toaster, Radios und Mobiltelefone, „Enterprise-Edition“ (JavaEE, JEE oder J2EE) für die ganz großen Server, die Sun auch gerne selber verkauft hat und „Standard-Edition“ (JavaSE) für „normale“ Aufgaben. Diese Aufteilung hat sich ein bisschen relativiert. Von JavaME hört man heute weniger, weil die Mobiltelefone heute leistungsfähig genug für JavaSE wären, wenn man es sich antun wollte, sogar für JavaEE. Die Programmierung von Toastern, Radios und Waschmaschinen ist ein Spezialgebiet, „embedded-Entwicklung“, mit dem man auch in der Informatik nur selten zu tun hat und diese Dinge nimmt man auch im Alltag kaum als Software wahr. JavaEE war in den ersten 10 Jahren einfach nur ein Rezept, um Programme langsamer, größer, komplizierter, störanfälliger und schlechter wartbar zu machen. Und man hatte plötzlich Abhängigkeiten vom Applikationsserver, die zwar idealerweise nicht den Programmtext selbst, wohl aber die Tonnen von XML-Konfiguration und die Deployment-Prozesse betraf. Da haben sich dann andere Frameworks entwickelt, zum Beispiel Spring, die etwas weniger schwerfällig daherkamen. Und für die Persistenz in JavaEE etablierte sich Hibernate und Eclipselink, was auch in JavaSE verwendbar ist. Nennt man nun eine Applikation, die mit Spring und Hibernate arbeitet, JavaEE oder JavaSE? Ich habe beides gehört. Jetzt sollte man bitte nicht versuchen, eine Applikation so zu entwickeln, dass sie wahlweise mit Spring und dem „Original-JavaEE“ läuft.

In den späten 90er-Jahren hatten Browser JavaSE eingebaut, damit man Applets schreiben konnte. So zeichnete es sich ab, dass jeder Rechner, den man kauft, eine gewisse Ausstattung bekommt, zum Beispiel einen Browser und eine Java-Installation. Dann hätten Java-Programme auf allen Desktop-Rechnern laufen können. Vielleicht müsste die Version hoch genug sein, weil Java sich natürlich weiterentwickelt hat und gelegentlich auch auf JavaVM-Ebene Erweiterungen nötig waren. Mit einem gute Software-Update-Mechanismus, wie wir ihn heute bei Linux-Distributionen oder bei den meisten Mobiltelefonen finden, hätte sich das lösen lassen. Dumm war nur, dass es eine Zeit gab, wo noch viele Anwender ein Modem mit 56k hatten und wo eine Java-Installation 80 MB groß war. Dann ist aber irgendwann, etwa nach dem Jahr 2000, die Java-Installation auf gängigen PCs selten geworden und man musste Endkunden bei der Installation von Java (wohlgemerkt 80 MB über das Modem) supporten, um ihre Java-Installation zum Laufen zu bringen. Das konnte sich nur in wenigen Fällen lohnen und man hat lieber auf Web-Applikationen gesetzt, was sich weitgehend durchgesetzt hat. Und die Browser können heute JavaScript, aber kein Java.

Bei den Mobiltelefonen gab es einige vielversprechende Anläufe, um Software-Entwicklung für eine Vielzahl von Geräten auf einmal zu ermöglichen. JavaME war eigentlich keine schlechte Idee, weil das auch auf recht kleinen Telefonen lief und auf den dicksten Smartphone könnte man es auch haben. Ein anderer Ansatz, der vielleicht ein bisschen weniger bekannt ist, ist die Verwendung des Qt-Frameworks für C++. Das ermöglicht auch auf einer Vielzahl von Geräten vom Arbeitsplatzrechner mit Linux oder MS-Windows bis zum Mobiltelefon „dieselbe“ Software laufen zu lassen, natürlich mit kleinen Anpassungen, um dem Benutzerinterface Rechnung zu tragen, und mit einer Neucompilierung für die Zielplattform. Diesen Weg hat Nokia verfolgt, als sie noch ernsthaft Mobiltelefone entwickelt haben und Qt-Applikationen liefen auf Symbian und Linux-Geräten (N900, N9), womit die Umstellung von Symbian auf Meego-Linux innerhalb kürzester Zeit eine reiche Auswahl an Apps für die neue Plattform ermöglicht hätte. Da Nokia sich aus der Mobiltelefonieentwicklung weitgehend und aus Meego und Symbian ganz zurückgezogen hat, bietet sich hier die Chance für neue Anbieter, wie zum Beispiel Jolla, mit dem Knowhow der ehemaligen Nokia-Mitarbeiter und deren vielversprechenden Ideen in den Markt einzusteigen und einen Teil der Rolle, die Nokia einmal hatte, zu übernehmen. Für native Apps auf dem Mobiltelefon ist aber aus heutiger Sicht die Dalvik-Engine von Android das mit Abstand zukunftsträchtigste Modell. Das ist letztlich eine weitere Java-„Edition“ und ermöglicht immerhin eine Lauffähigkeit auf dem überwiegenden Teil der neu verkauften Smartphones. Neue Linux-basierte Mobiltelefon-Betriebssysteme haben zum Teil die Möglichkeit integriert, für Dalvik geschriebene Android-Apps auszuführen. Aber einige Anbieter fahren bewusst die Schiene der Inkompatibilität ihrer Geräte und verlangen so eine Eigeneentwicklung nur für diese. Das schöne daran ist, dass dieser Ansatz scheitern wird, sobald die Marktanteile nicht mehr so groß sind. Hier werden sich wahrscheinlich Web-Applikationen durchsetzen.

Was Java betrifft, ist dessen Domäne heute neben Android-Telefonen im Serverbereich. Tatsächlich laufen Java-Applikationen ja mit hinreichend neuen JavaVM-Installationen oft auf allen Servern, wenn bei der Entwicklung gewisse Einschränkungen beachtet wurden. Ein Java-Programm, das seine Konfiguration in „C:/Programme/myCoolApp/config.properties“ sucht, wird auf Linux-Servern eher nicht das gewünschte finden, obwohl die „forward-slashes“ in Java-Programmen auch unter MS-Windows empfehlenswert sind und funktionieren. Aber es gibt immer noch genug potentielle Probleme, zum Beispiel mit Bibliotheken, die von der Java-Applikation benötigt werden, aber die inkomptabil zu der gewünschten Tomcat-Version sind, weil dort eine ältere Version derselben Bibliothek integriert und verwendet wird. Bis zu einem gewissen Grade lassen sich solche Probleme lösen und man findet immer wieder coole Ideen, die das ganz vollständig lösen wollen, wie z.B. OSGi. Mit entsprechendem Aufwand geht es auch tatsächlich in vielen Fällen, aber gewisse Bibliotheks-Inkomptabilitäten lassen sich nicht so leicht aus der Welt schaffen. so bleibt das „write once – run everywhere“ ein Versprechen, an dem viel Wahres dran ist, das aber auch seine Grenzen hat.

Nebenbei bemerkt ist das gar nicht so sehr die Eigenheit von Java. Qt mit C++ wurde schon erwähnt. Aber auch Perl, Ruby, Python, Oracle, C# (mit Mono), Lua, TeX und viele andere können ein ähnliches Versprechen wie Java abgeben und dieses ähnlich gut und mit ähnlichen Einschränkungen halten. Vielleicht ist es in Java schwieriger, nicht-triviale Dinge zu tun, die spezifisch für eine Plattform sind. Und vielleicht reicht Java in gewissen Bereichen mit diesem Versprechen etwas weiter als andere, aber für typische Server-Applikationen stimmt das „write-once-run-everywhere“ für Ruby-on-Rails mindestens genauso wie für Java-Web-Applikationen.

Share Button