zurück zum Artikel

Java als universelle Programmiersprache

Dr. Lofi Dewanto, Manuel Klein
Java als universelle Programmiersprache

Nach etlichen Jahren der Entwicklung ist Java zur erwachsenen Allzweck-Programmiersprache geworden.

Immer wieder stand Java in der Kritik: Sei es wegen schlechter Performance, fehlenden Features wie Mehrfachvererbung, mangelnden funktionalen Aspekten, mangelhafter Ausnutzung moderner Prozessorarchitekturen oder der Umständlichkeit der Programmierung. Bei Betrachtung der Java Enterprise Edition (Java EE), um von früheren Versionen des J2EE-Zeitalters gar nicht erst zu sprechen, ist der Tonfall der Java-Gegner noch deutlich gereizter. Dennoch steht Java bei den beliebtesten Programmiersprachen immer noch an der Spitze oder zumindest auf einem der ersten Plätze [1]. Die Geburt neuer und vielfältiger Programmiersprachen konnte Java letztlich nicht von der Pole-Position verdrängen.

Vor über vier Jahren hat Lofi Dewanto, einer der beiden Autoren dieses Artikels, mit einem Beitrag auf heise Developer [2] zu seinem Wunsch zu einem verstärkten Einsatz von Java als Allzweck-Programmiersprache eine kontroverse Diskussion erzeugt. Es lohnt sich, einen aktualisierten Blick auf die Entwicklung zu werfen – die Anzahl der Java-Herausforderer dürfte nicht kleiner geworden sein. Im folgenden Artikel beschäftigen sich die Autoren mit der Alltagstauglichkeit von Java und möglichen Bedrohungen sowie der Frage, ob sich Java mit Compilern, Transpilern, virtuellen Maschinen und Erweiterungen sinnvoll als Allzweck-Programmiersprache einsetzen lässt.

Bei Betrachtung der Frage, wie es mit Java weitergeht, kann man die diesbezüglichen Statements in zwei Kategorien einteilen. Erstens Aussagen über Java an sich, zweitens über neue Sprachen oder Konzepte, die Java bedrohen. Als Produkt von Sun Microsystems konnte sich Java bei ständig wachsender Beliebtheit recht beschaulich weiterentwickeln. Mit der Akquise seitens Oracle 2010 hat sich das grundlegend geändert. Im Gegensatz zum Vorbesitzer hat Oracle eine Größe, die in der IT-Welt ein natürliches Misstrauen erzeugt. Nach sechs Jahren lässt sich zumindest festhalten, dass Oracle Java durchaus Beachtung schenkt.

Hinsichtlich Java EE hat Oracle allerdings gerade in den letzten Jahren wenig Engagement gezeigt, was im letzten Jahr unter anderem zur Gründung der Java EE Guardians, einer von Oracle unabhängigen Initiative zur Förderung von Java EE geführt hatte. Es ist ziemlich sicher, dass sich Java EE von behäbigen, schwergewichtigen Applikationsservern weg hin zu einfachen Architekturen bewegen muss. Das scheint auch Oracle erkannt zu haben [3]. Schließlich gibt es immer noch das Spring Framework, das derzeit beispielsweise mit Spring Cloud und Spring Boot wieder einmal beweist, wie einfach sich Java in zeitgemäßen Architekturen einsetzen lässt.

Das Einsatzgebiet von Java reicht heute von serverseitigen Webapplikationen bis hin zu Anwendungen für Smartphones, Raspberry Pi und Haushaltsgeräten wie Kaffeemaschine, Spülmaschine und Toaster. Java wird somit wohl noch einige Zeit eine wichtige Rolle in der IT-Welt spielen, und auch die rund 100.000 Java-Programmierer in Deutschland [4] müssen sich nicht allzu bald ein neues Betätigungsfeld suchen. Nicht zu verschweigen ist jedoch, dass es derzeit einige Bereiche gibt, in denen Java durchaus zurückgedrängt wird:

Trotz der zahlreichen Alternativen bleibt die Frage bestehen: Können Java-Entwickler auch in den nächsten Jahren mit einer einzigen Programmiersprache alle Aufgaben ökonomisch sinnvoll bewältigen und milde lächelnd auf die Angriffsversuche vermeintlicher Alternativen herabschauen? Oder werden sie sich anpassen müssen?

Als Basis für sämtliche Diskussionen über den universellen Einsatz von Java dienen die Applikationstypen heutiger Anwendungsentwicklung. Folgende sollen sich generell von einem Produkt beziehungsweise einer Applikation bedienen lassen:

Im Bereich der Standalone-Anwendungen auf den Desktop-Betriebssystemen kann Java seine volle Stärke ausspielen. Mit UI-Frameworks wie Swing, SWT und JavaFX wurden komplexe Desktop-Anwendungen sowie unter anderem typische Entwicklerwerkzeuge wie IntelliJ IDEA (Swing), Eclipse (SWT), NetBeans (Swing) und MagicDraw UML (Swing) implementiert. Dank der JVM laufen diese Anwendungen in Windows, macOS und Linux, ohne dass Programmänderungen erforderlich sind.

In diesem Bereich ist Java praktisch gesetzt, auf das Paradigma "Write Once, Run Anywhere" kann man sich voll verlassen. Die einzige Alternative ist, ganz auf die Microsoft-Welt zu setzen. Insbesondere Swing erfreut sich trotz einiger Designfehler und geringer Beachtung durch Sun beziehungsweise Oracle einer großen Beliebtheit und erlaubt Java-Entwicklern, schöne und schnelle Benutzeroberfläche umzusetzen.

Als Nachfolger für Swing steht JavaFX bereit, allerdings muss man hier von einem holprigen, sich über Jahre hinziehenden Start sprechen. Das geht soweit, dass immer noch nicht wenige gar von einer Totgeburt sprechen. Anderseits nimmt das Interesse an JavaFX mittlerweile anscheinend zu. Last, but not least gibt es diverse weitere Plattformen und Frameworks für das Erstellen von Standalone-Java-Anwendungen, beispielsweise die Eclipse Rich Client Platform (RCP) und die NetBeans Platform. Allerdings hat die Bedeutung von Standalone-Anwendungen in den letzten Jahrendank zunehmend leistungsfähiger Webframeworks drastisch abgenommen – ein Trend, dessen Ende nicht abzusehen ist.

Eine Webanwendung besteht in aller Regel aus zwei Teilen (Datenbanken und andere zu integrierende Systeme müssen hier nicht betrachtet werden):

In der rein serverseitigen Webanwendung bietet Java viele Frameworks [9] sowohl für das serverseitige Erstellen von Benutzeroberflächen als auch für die Implementierung der Businesslogik an: Spring MVC, JSF-basierte Web-Frameworks, Vaadin, Struts, Wicket, Play Framework sind einige populäre Beispiele für serverseitige Benutzeroberflächen-Frameworks. Bezüglich der Businesslogik stehen Java EE und Spring Framework mit ihren beinahe unbeschränkten Möglichkeiten zur Verfügung.

In heutigen Webanwendungen spielt jedoch die grafische Oberfläche eine große Rolle. Typische Webanwendungen der Vergangenheit mit endlosen Formularen und Fehlermeldungen, die erst nach dem Klick auf OK erschienen, akzeptieren Nutzer nicht mehr. Mit HTML5, CSS und JavaScript werden interaktive Anwendungen innerhalb ihres "natürlichen Lebensraums", des Webbrowsers, umgesetzt.

Wie geschildert, lösen Webanwendungen die Standalone-Anwendungen Schritt für Schritt ab. So wurde Google Picasa (Desktop) durch Google Photos (Web) ersetzt. Eclipse Che [10] ist komplett als Webanwendung umgesetzt und kann sowohl auf dem Server als auch komplett auf dem Desktop laufen. Die IDE hat somit das Potential, zur Alternative des heutigen Eclipse [11] zu werden.

Sämtliche Webanwendungen lassen sich lokal als Desktop- und Standalone-Anwendungen mithilfe eines integrierten Webbrowsers und Webcontainers installieren und ausführen. In vielen Fällen können beispielsweise Chrome Apps Standalone- und Desktop-Anwendungen ersetzen. Sämtliche Systemzugriffe werden sowohl generell von HTML5 als auch von der Chrome Plattform angeboten.

Java-Techniken, welche die clientseitige Ausführung von Webanwendungen erlauben, wie Java-Applets oder Java Web Start haben sich nicht durchgesetzt und lassen sich heute ebenso wie ihre Pendants außerhalb der Java-Welt (Flash, Silverlight) ignorieren. HTML5, CSS und JavaScript sind derzeit De-facto-Standards für die Implementierung der Benutzeroberfläche auf Basis eines Webbrowsers. Müssen Java-Entwickler, zumindest was die GUI anbetrifft, also doch ihre gewohnte Entwicklungsumgebung verlassen und sich mit JavaScript und Konsorten beschäftigen? Analog zur Bewegung, JavaScript mit Node.js auf den Server zu bringen, gibt es einige Projekte [12], die indirekt den Einsatz von Java auf dem Webbrowser ermöglichen [13].

Verallgemeinert gesprochen wird dazu entweder der Java-Code auf die ein oder andere Art in JavaScript übersetzt oder eine Java Virtual Machine (JVM) in JavaScript implementiert. Tabelle 1 zeigt einige Werkzeuge für die Nutzung von Java für Webanwendungen.

Produkt Typ Bemerkung
GWT [14] (früher: Google Web Toolkit) Java-zu-JavaScript-Transpiler auf Quellcode-Ebene mit JRE-Emulation Etablierter (knapp 10 Jahre alt [15]!) Java-zu-JavaScript-Transpiler, beinhaltet außerdem Benutzeroberflächen-Elemente, ein Client-Server-Kommunikationsprotokoll und andere Dinge, die eine komplette Umsetzung einer Webanwendung ermöglichen. GWT wird aktuell für komplexe Webanwendungen bei Google und auch bei Eclipse Che verwendet. Die neueste GWT Version 2.8.0 wurde im Oktober 2016 [16] mit Java 8 und besserer JavaScript-Interoperabilität veröffentlicht. Einen aktuellen Überblick über GWT (auch J2CL) sowie dessen Zukunft findet sich hier. [17]
JSweet [18] Java-zu-JavaScript-Transpiler auf Quellcode-Ebene, keine Emulation zu Java-Standard-Klassen Ähnlich wie GWT, jedoch mit eigens entwickelten Basisklassen, die sehr an JavaScript angelehnt sind. Der Benutzer kann also seine gewohnten Entwicklungswerkzeuge und die Java-Syntax nutzen, um JavaScript zu implementieren [19].
ST-JS (Strongly Typed JavaScript) [20] Java-zu-JavaScript-Transpiler auf Quellcode-Ebene, keine Emulation zu Java-Standard-Klassen Einfacher Transpiler, sehr ähnlich zu JSweet
Java2Script [21] (J2S) Java-zu-JavaScript-Transpiler auf Quellcode-Ebene mit JRE-Emulation Dieser Transpiler übersetzt den Java- zu JavaScript-Code [22], ähnlich wie GWT. Speziell zu diesem Transpiler ist die Integration für Eclipse SWT [23]. Eclipse SWT wurde aus Java in JavaScript übersetzt und kann so auf dem Browser verwendet werden [24].
TeaVM [25] Java-Bytecode-zu-JavaScript-Transpiler TeaVM kompiliert den Java-Bytecode zu JavaScript [26]. Java-Quellcode wird hierfür nicht benötigt. TeaVM bietet einige Möglichkeiten zur Integration von bereits vorhandenen JavaScript-Code [27]ähnlich wie in GWT an.
Bck2Brwsr [28] Java-Bytecode-zu-JavaScript Transpiler Sehr ähnlich zu TeaVM [29]
DoppioJVM [30] JavaVM auf Basis von JavaScript DoppioJVM ist eine Java Virtual Machine, die 100 Prozent in JavaScript (bzw. TypeScript) geschrieben wurde [31]. Die Idee ist, dass die Java-Anwendungen, ohne Änderung auf dem Browser, innerhalb dieser Virtual Machine laufen können.
DukeScript [32] Generelles Framework, nicht nur für Webbrowser DukeScript passt nicht zu der Kategorie Transpiler oder JavaVM auf Basis von JavaScript. DukeScript ist ein Java-basiertes Framework mit Knockout [33] als Data-Binding-Framework. Die Modelle für das Data Binding werden in Java umgesetzt. Um die Anwendungen auf dem Browser laufen zu lassen, wird Bck2Brwsr oder TeaVM benötigt. DukeScript erlaubt, ähnlich wie GWT, einen direkten Zugriff von Java auf JavaScript [34].

Hierbei fällt auf, dass Oracle, also der Besitzer von Java, kein einziges Produkt bietet, mithin kein rechter Wille zu erkennen ist, hier Java voranzubringen. Statt sich mit die Verbesserung und Verbreitung von Java zu beschäftigen, bietet Oracle mit JET (JavaScript Extension Toolkit) eine JavaScript-Framework-Sammlung an. Positiv anzumerken ist, dass Oracle keinen erneuten Versuch startet, das Rad neu zu erfinden – das Application Development Framework (ADF) sei an dieser Stelle als abschreckendes Beispiel genannt. Schaut man an der Stelle aber beispielsweise auf die JSF-Komponentenbibliothek Primefaces, besteht Anlass zu einer gewissen Verwunderung. Sie ermöglicht es, ohne weiteres ansprechende, moderne Weboberflächen zu programmieren. Leider ist von Seiten Oracles wenig Enthusiasmus zu spüren, die konzeptionellen Schwächen von JSF zu verringern.

Darüber hinaus zeigt alleine die pure Masse an Java-zu-JavaScript-Transpilern das große Interesse an ihnen. Oracle scheint in diesem Bereich jedoch nichts auf dem Plan zu haben. Nichtsdestotrotz ist es mit den Alternativen aus Tabelle 1 möglich, Webanwendungen mit HTML5, CSS und Java zu entwickeln, ohne JavaScript einzusetzen.

Für die mobilen Anwendungen ("Apps") auf Smartphones und Tablets gibt es heute praktisch nur noch zwei Betriebssysteme (iOS und Android), die sich den Markt aufteilen. Aus ihnen abgeleitet werden Derivate wie watchOS, tvOS, CarPlay sowie Android Wear, TV, Auto umgesetzt. Um mobile Anwendungen zu implementieren, gibt es zwei Wege mit diversen Varianten: hybride Anwendungen auf Basis von HTML, CSS und JavaScript und native mobile Anwendungen. (Echte Webanwendungen ignorieren die Autoren hier, da sie sich aus technischer Sicht nicht von Webanwendungen auf dem Desktop unterscheiden.)

  1. Hybride Anwendungen auf Basis von HTML, CSS und JavaScript: Sie laufen auf einer sogenannten Webview beziehungsweise einem Webcontainer, also einem eingebetteten Webbrowser. Sie findet man auf allen mobilen Geräten, die Webview (HTML, CSS und JavaScript) unterstützen. Hier spielen Techniken wie Apache Cordova und Adobes PhoneGap (basierend auf Cordova) eine große Rolle. Ähnlich wie bei den anderen Webanwendungen existieren im mobilen Umfeld Angebote mit Java statt JavaScript. Die Open-Source-Produkte mGWT beziehungsweise mGWT Phonegap sind ein Beispiel. Einer der gravierenden Nachteile einer hybriden Anwendung ist das Look-and-feel der Benutzeroberfläche, die sich oft nicht "nativ" anfühlt. Zwar ist es möglich, geräteabhängige Verhaltensweisen zu implementieren, allerdings geht dann schnell die durch den hybriden Ansatz eingesparte Zeit wieder verloren.
  2. Native mobile Anwendung: In der Android-Welt ist Java zu Hause, und gleichzeitig ist Android dank Java so erfolgreich. Quellcode in Java aus Standalone- und Webanwendungen lässt sich relativ leicht in nativen Android-Anwendungen wiederverwenden. Geschäftslogik kann theoretisch einfach neu kompiliert werden, auch wenn sich die Architektur auf einem mobilen Gerät in aller Regel von derjenigen einer herkömmlichen Anwendung unterscheiden wird. Die Benutzeroberfläche ist in jedem Fall neu zu programmieren.

Für das Betriebssystem iOS gibt es einige Frameworks für die Implementierung einer nativen Anwendung mit Java:

Produkt Typ Bemerkung
Titanium4J [35] JavaScript-basierende plattformübergreifende Laufzeitumgebung Titanium4J basiert auf dem Produkt Titanium. Vergleich zwischen Phonegap und Titanium [36]
Gluon [37] JavaFX-basierende Plattform für alle Betriebssysteme inkl. Android und iOS Architekturdokumentation von Gluon-Anwendungen [38]
J2ObjC [39] Java-zu-Objective-C-Transpiler Mit J2ObjC können keine komplett nativen Anwendungen für iOS geschrieben werden. Dieser Transpiler dient zur Wiederverwendung von Java-Logik-Code in Objective-C. Sämtliche Benutzeroberflächen müssen immer noch in Objective-C bzw. Swift geschrieben werden. Dieses Framework vereint natives Look-and-feel und Wiederverwendung von Java-Quellcode. Eine Erklärung, wie Google Java für Web (GWT), Android und iOS (J2ObjC) nutzt, findet sich hier [40].
JUniversal [41] Java-zu-C#-Transpiler Möchte jemand für die Windows Plattform entwickeln, steht JUniversal von Microsoft für die Umsetzung mit Java zur Verfügung. Das Konzept ähnelt demjenigen von J2ObjC. Einführungsartikel zu diesem Thema [42]

Die ständige Weiterentwicklung der Webbrowser im Desktop und mobilen Umfeld bringt derzeit eine neue Alternative für die Entwicklung hervor: Progressive Web Apps (PWA [43]). Sie lassen sich sowohl für Desktop- als auch für mobile Webapplikationen, die jedoch Charakteristiken einer nativen mobilen Anwendung besitzen.

Konzept der Progressive Web Apps im Überblick

Konzept der Progressive Web Apps im Überblick (Abb. 1)

Es ist zu sehen, dass Mobile-Entwickler mit HTML, CSS und Java für die Zielplattformen Android und iOS auskommen. Falls natives Look-and-feel benötigt wird, können Entwickler die Wiederverwendung von Java-Code mit Transpilern wie J2ObjC erhöhen. Allerdings zeigen Entwicklungen wie PWA, dass sich JavaScript im Browser ganz zu Hause fühlt. Mit Transpilern wie GWT lässt sich PWA ebenfalls in Java implementieren [44].

Internet of Things (IoT) ist derzeit in aller Munde. Hier spielt Java ebenfalls eine große Rolle. Eclipse IoT bietet zum Beispiel eine Sammlung von Open-Source-Projekten, die für IoT-Umgebungen wie Raspberry Pi gedacht sind. Für LEGO-Fans gibt es das Projekt Lejos (Java for LEGO Mindstorms). Zwar wird Java -- insbesondere der JVM – immer wieder nachgesagt, Ressourcen zu verschwenden, trotzdem findet sie auch in Bereichen mit wirklich eingeschränkten Kapazitäten Verwendung. Offensichtlich überwiegen die Vorteile der weitreichenden Möglichkeiten den Einschränkungen, welche die limitierte Hardware mit sich bringt.

Zusammengefasst ist Java alternativlos für sämtliche Entwickler, die ausschließlich mit einer einzigen Programmiersprache implementieren wollen. Desktop mit Standalone-, Web- und mobilen Anwendungen, Raspberry Pi und Lego Mindstorms lassen sich in Java programmieren. Keine andere Programmiersprache ist so universell einsetzbar. Möchte heute jemand eine Anwendung erstellen, kommen folgende Java-Techniken in Frage:

Schließlich gibt es noch einen ganz anderen Aspekt: Im Bereich der JavaScript-Frameworks – Angular(JS), React et cetera – ist es im Augenblick kaum absehbar, wie sich der Markt weiter entwickeln wird. Selbst der Vergleich von AngularJS 1 und Angular 2 wirft noch Fragen auf: "Was mache ich mit meinen AngularJS-1-Anwendungen?", "Soll ich nun auf TypeScript setzen?". Im Java-Umfeld gab es einen vergleichbaren Kampf vor einigen Jahren mit beispielsweise JSF, Wicket, Vaadin und Spring MVC auch, allerdings hat sich der Markt stabilisiert. Transpiler wie GWT erlauben zudem die Übersetzung von Java in das native clientseitige JavaScript. Gleichzeitig gibt es für wirklich jeden nur denkbaren Einsatzzweck mindestens ein Framework, das vom zugrunde liegenden System abstrahiert.

Java-Einsatz im Überblick (Abb. 2)

Java-Einsatz im Überblick (Abb. 2)

Nach etlichen Jahren ist Java als Allzweck-Programmiersprache erwachsen geworden. Schade, dass sich Oracle an dieser Stelle relativ mut- und ideenlos verhält, geschweige denn Initiative in Java-zu-JavaScript-Transpiler-Projekten übernimmt.

Lofi Dewanto
arbeitet als Teamleiter der Softwareentwicklung beim Umweltdienstleister Interseroh Dienstleistungs GmbH in Köln. Er engagiert sich insbesondere für "javanische" Open-Source-Software sowie MDA.

Manuel Klein
arbeitet als Fachbereichsleiter Enterprise Java Development bei der MT AG in Ratingen. Neben der Programmierung mit Java EE beschäftigt er sich gemeinsam mit seinem Team mit den aktuellen JavaScript-Frameworks sowie hybriden Apps.
(ane [45])


URL dieses Artikels:
https://www.heise.de/-3742037

Links in diesem Artikel:
[1] https://www.heise.de/news/Programmiersprache-des-Jahres-ist-Java-3583597.html
[2] https://www.heise.de/hintergrund/Warum-Polyglot-Programming-nicht-praxistauglich-ist-1479542.html
[3] https://www.heise.de/news/Oracle-bricht-das-Schweigen-zu-Java-EE-8-3258781.html
[4] https://www.heise.de/news/Stack-Overflow-Ueber-700-000-Softwareentwickler-in-Deutschland-3328648.html
[5] http://news.dartlang.org/2016/03/the-new-adwords-ui-uses-dart-we-asked.html
[6] https://channel9.msdn.com/events/Visual-Studio/Connect-event-2015/076
[7] https://www.heise.de/news/Google-erwaegt-Swift-angeblich-als-Programmiersprache-fuer-Android-3166346.html
[8] https://www.heise.de/meinung/Kommentar-Kotlin-fuer-Android-Googles-fremde-Lorbeeren-3717940.html
[9] https://zeroturnaround.com/rebellabs/java-tools-and-technologies-landscape-2016/
[10] https://www.heise.de/hintergrund/Eclipse-Che-die-IDE-der-Zukunft-3266413.html
[11] https://dzone.com/articles/the-evolution-and-future-of-ides
[12] https://github.com/jashkenas/coffeescript/wiki/List-of-languages-that-compile-to-JS
[13] http://javapapers.com/java/run-java-in-javascript/
[14] http://www.gwtproject.org
[15] https://www.quora.com/Does-GWT-has-a-future
[16] https://www.heise.de/news/Webframework-GWT-2-8-mit-finaler-Java-8-Unterstuetzung-und-besserer-JavaScript-Integration-3356431.html
[17] https://www.toptal.com/front-end/javascript-front-ends-in-java-with-gwt
[18] http://www.jsweet.org
[19] http://www.jsweet.org/comparing-the-gwt-transpiler-and-jsweet
[20] http://st-js.github.io/
[21] http://j2s.sourceforge.net/
[22] http://j2s.sourceforge.net/j2s-user-guide/dist/j2s-user-guide-htmls/chap-intro.html#sec-what-is-java2script
[23] http://j2s.sourceforge.net/j2s-user-guide/dist/j2s-user-guide-htmls/comparing-j2s-with-similar-techs.html
[24] http://j2s.sourceforge.net/j2s-user-guide/dist/j2s-user-guide-singlehtml/j2s-user-guide.html#AEN416
[25] http://teavm.org
[26] https://github.com/konsoletyper/teavm/wiki/Pipeline
[27] https://github.com/konsoletyper/teavm/wiki/Interacting-with-JavaScript
[28] http://wiki.apidesign.org/wiki/Bck2Brwsr
[29] https://github.com/konsoletyper/teavm/wiki/Comparison-to-Bck2Brwsr
[30] http://doppiojvm.org
[31] https://github.com/plasma-umass/doppio
[32] https://dukescript.com
[33] http://knockoutjs.com
[34] https://dukescript.com/update/2015/01/04/Common-misconceptions-about-DukeScript.html
[35] https://ahome-it.com/titanium4j
[36] http://www.appcelerator.com/blog/2012/05/comparing-titanium-and-phonegap
[37] http://gluonhq.com
[38] http://docs.gluonhq.com/charm/4.1.0
[39] http://j2objc.org
[40] https://www.infoq.com/news/2014/11/google-inbox-cross-platform
[41] http://juniversal.org
[42] http://www.infoworld.com/article/2879090/java/microsoft-backs-java-for-cross-platform-mobile-apps.html
[43] https://www.heise.de/ratgeber/Zukunft-der-Webentwicklung-Webkomponenten-und-Progressive-Web-Apps-Teil-1-3355449.html
[44] http://www.g-widgets.com/2016/08/11/progressive-web-apps-recipes-for-gwt/
[45] mailto:ane@heise.de