Was ein Gefuddel für Android

Nachdem mir die Raspberry PIs als auch vergleichbare Platinen im Moment einfach zu teuer sind, habe ich mich daran gemacht, ein uraltes Notebook, dass ich vor einigen Monaten mit Deepin Linux neu eingerichtet habe, für die Cordova-Entwicklung einzurichten. Das ist zwar fertig, liegt aber sowieso da rum und einen Test war es mir wert.

Im Grunde geht das Einrichten von Cordova ja auch recht einfach, wenn es nicht die elenden Fallen geben würde.
Einmal ist da im Fall von Android das Problem mit der Java-Version. So richtig geht es – falls man für Android die App erstellen will – nur mit Java 8 bzw. dem JDK 8. Das Problem habe ich schon vor gefühlten Ewigkeiten bemerkt und mir immer damit geholfen, dass ich eben Java 8 installiert habe. Neben den aktuellen Versionen. Leider ist es dann aber blöde, weil man für Gradle-Skripte (zumindest die vorgefertigten von Cordova) die Default-Version von Java auch auf eben dieses Java 8 umstellen muss. Das geht in Linux (Debian, Ubuntu, Mint und Derivate) so:

sudo update-alternatives --config java

In der Folge kann man zwischen den installierten Java-Versionen auswählen und eine davon zur Default-Version machen. Aber dann muss man dann auch noch JAVA_HOME korrekt setzen. Etwa so:

env JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64/

oder

export JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64/

Ging unter Deepin als normaler User, aber komischer Weise hat das als root nicht funktioniert bzw. die Einstellungen wurden nicht übernommen. Letztendlich habe ich viel rumgebastelt, wieder viel gelernt, bin aber wie so oft im Grunde gescheitert.
Wobei das Problem mit Java 8 ist vermutlich ein ganz anderes, als man vermutet. Denn vor einigen Monaten hatte ich eine Schulung rund um Java EE gehalten und da hatten wir bei JSF ein ähnliches Problem. Die Meldung sah so aus als wäre die Version von Java nicht passend bzw. zu alt, obwohl sie neuer als die geforderte/angezeigte Version war. Ganz wie hier bei Cordova. Aber dann ist mir aufgefallen, dass die Versionsnummern in dem Framework nur einstellig (!) evaluiert wurden. Also Java 11 oder Java 17 werden als Java 1 interpretiert. So was vermute ich mittlerweile auch bei Cordova bzw. den Gradle-Skripten. Man müsste es mal mit Java 9 testen, aber dazu habe ich im Moment keine Zeit.
Letztendlich ist aber sowieso das Hauptproblem dieses elende Android-Gefuddel. Das Android-SDK und die Android-Tools etc. habe ich nach und nach alle installiert, aber ständig kam die Meldung, dass das Zeug nicht da wäre. Genaugenommen hat das Gradle-Skript diese Meldung gebracht. Letztendlich habe ich sogar das Android Studio auf dem uralten Notebook mit Deepin installiert, dort diverse Fernzugriffservice eingerichtet und gestartet, alle möglichen SDK-Versionen nachinstalliert und sogar ein Cordova-Template im Android Studio als Plugin eingerichtet.
Resultat – das Gradle-Skript weigert sich, die Android-Ressourcen zu finden. Und selbst das Android Studio nimmt dieses Gradle-Skript und kennt sich quasi dann selbst nicht mehr.

Irgendwann hatte ich die Faxen dicke, denn so schön Deepin Linux von der Oberfläche auch ist – es hat so ein paar Macken, die ich von der administrativen Seite nicht wirklich gut finde. Und der VNC- als auch RDP-Zugriff haben darauf ums Verrecken nicht funktioniert. Nur ssh – auch mit X-Umleitung von einem anderen Linux-Rechner.
Apropos anderer Linux-Rechner – das ist mein Terra-Notebook, auf dem ich Windows 10 und Mint Linux im Dualboot betreibe. Unter Windows habe ich das Cordova (auch für Android) mit Visual Studio 2017 im Griff (und im Prinzip auch mit dem Android Studio – das macht aber keinen Spass). Die Linux-Version kann ich aber seit Monaten nicht mehr aktualisieren oder da ein Programm installieren. Die Sache hier war für mich der Anlass, dass Problem mal anzugehen. Denn egal was ich probiert habe die letzte Zeit – mit der Fehlermeldung, dass die Quellen nicht zu lesen wären, haben sämtliche Aktualisierungsversuche als auch Installationsversuche abgebrochen.
Ich bin nun auf den Lösungsansatz gestoßen, dass man die Datei mit einem geeigneten Repo füllen sollte. Etwa das:

sudo nano /etc/apt/sources.list
deb http://de.archive.ubuntu.com/ubuntu bionic main restricted

Habe ich gemacht – keine Wirkung!
Dann habe ich endlich die Meldung genauer angesehen – Linux hat nicht die Datei /etc/apt/sources.list beim Installieren/Aktualisieren ausgelesen, sondern die Datei /etc/apt/sources.list.d/vivaldi.list.
Aus irgendeinem Grund wurde der Pfad umgebogen. Wo genau, habe ich noch nicht raus, aber einfach das Repo da reingeschrieben. Und gut ist es – aktualisieren und installieren geht wieder.
Jetzt kann ich auch mal den Linux-Rechner nutzen und versuchen, da Cordova-Apps für Android zu kompilieren. Wenn das auch da nicht geht, habe ich ja immer noch Visual Studio 2017 und meinen Docker-Container.

Und so ganz unwahrscheinlich ist es nicht, dass ich darauf beschränkt bleibe. Denn bei dem Mint-Linux ist node.js und damit auch npm in einer alten Version dabei. Was nicht schlimm wäre, wenn nicht jede Art der Installation, die ich versucht habe, immer diese uralte Version 8 installiert hätte. Mit apt bzw. apt-get entfernt, neu installiert, andere Quellen genommen, verschiedene Package-Manager ausprobiert -> immer die Version 8, obwohl es schon die Version 18 gibt. Ein Problem führt bei den ganzen Aktionen – wie eigentlich immer – zum nächsten.

Ich bin jetzt auf das Level zurückgegangen, dass ich die Quellcodes von Git geholt und dann bei mir neu kompiliert und installiert habe.

Also klassisch

git clone https://github.com/joyent/node.git

Und dann:

./configure
make
make install

Dazu gibt es im Netz eine ziemlich gute Anleitung.

Der kleine Hinweis dort, dass das Kompilieren ein „bisschen länger“ dauert, war aber untertrieben. Ich bin mit der Erwartung von vielleicht 30 Minuten maximal in den make-Befehl rein und nach gut 5 Stunden war noch kein Ende zu sehen. Das Zeug ist dann über Nacht durchgelaufen und heute morgen war es erledigt. Das dauert also brutal lang, wobei mein Terra-Notebook auch schon in die Jahre gekommen ist.

Anyway – die Sache ging durch und nun habe ich node.js bzw. npm in der Version 18. Cordova ist damit auch eben fix installiert und wie es mit Android aussieht, schaue ich mir später an. Das ist ja die einzige kritische Stelle.

 

JSF/MyFaces, Microservices, Maven & Co

Ich habe die ersten drei Tage der Woche eine Einzelschulung zu erweiterten Java-Themen gehalten. Es ist kaum zu glauben, aber das war die erste Live-Schulung seit 1,5 Jahren. Obwohl ich in der Zeit sogar sehr viele Schulungen gehalten habe, waren sie allesamt online.
Bei der Schulung ging es grob gesagt um Java. Aber keine Einsteiger-Themen, sondern um eine Betrachtung diverser Themen im Java-Umfeld samt Web für einen erfahrenen Programmierer, der sich mit den Techniken bereits auskennt. So Sachen wie

  • JUnit, Git und Github,
  • Maven und andere Build-Tools wie Gradle und Ant,
  • Docker,
  • Übersicht neue Java-Techniken (vor allen Dingen Lambda-Ausdrücke, Closures und das Modulsystem)
  • JavaFX/OpenJFX/FXML
  • Ausblick Mobile, Android Studio, Cordova
  • Tomcat bzw. Java-Container als Server (Wildfly)
  • JSP/Servlets/JSF
  • Refactoring
  • Microservices (Spring)

Bei der Anfrage hat mich allerdings das Thema JSF (Java Server Faces) doch schwer verwundert. Ich hatte in der Vergangenheit JSF durchaus mehrfach geschult, aber seit Jahren eigentlich nichts mehr damit zu tun. Und ich bin davon ausgegangen, dass das Thema JSF eigentlich ziemlich out ist. So hatte ich das auch schon vor einigen Jahren beurteilt und mich deshalb aus dem Themenkomplex weitgehend zurückgezogen. Die vereinzelten Anfragen zu JSF-Kursen habe ich auch immer abgelehnt. Überhaupt sah und sehe ich bei den Java-Frameworks für das Web eigentlich nicht (mehr) das große Potential. Weder bei JSF (oder gar Servlets/JSP), noch Spring oder Struts.

Aber mein Teilnehmer wechselt demnächst beruflich als IT-Leiter in eine Behörde, die wohl mit JSF 2.3 arbeitet. Alttechnologien halten sich oft ewig. Ich habe ja auch einen Standardkunden, der noch mit Cobol arbeitet.

Da diese Schulung als eine Art Workshop mit Wissensaustausch gewünscht war und JSF etc. nur einen Teil der Agenda ausgemacht hat, habe ich die Sache angenommen. JSF und Web haben wir dann auch geschlossen am dritten Tag abgearbeitet.

Rückblickend war es auch verdammt spannend, sich wieder in die Welt von JSF einzuarbeiten. Wobei dabei uns beim Voranarbeiten ganz interessante Phänomene untergekommen sind, von denen mir immer noch nicht ganz klar ist, ob wir auf den Grund der Tatsachen getaucht sind oder uns verirrt haben.

Gerade bei Java im Web-Umfeld ist m.E. erst einmal die Konfiguration die größte Einstiegshürde. Vor allen Dingen, wenn man da nicht täglich am Schaffen ist. Das fängt schon mit der Konfiguration der Server an. Ganz banal bei der lästigen Tomcat-Einstellung in der Datei tomcat-users.xml, wo mit

<role rolename="manager-gui"/>

<user username="admin" password="admin" roles="standard,manager-script,manager-gui" />

erst einmal freigeschaltet werden muss, dass der Server über das Webinterface administriert werden kann und war-Dateien überhaupt deployed werden dürfen. Mit Wildfly ist es auch nicht einfacher bzw. bequemer.

Da Maven in der Schulung ein großes Thema war, haben wir viel mit Architypes gearbeitet. Auch bei JSF, was wir in der Version 2.3 als Basis genommen haben. Neben den Schablonen in Netbeans und Eclipse, die mit Maven, Ant oder Gradle arbeiten.

Neben dem elenden Konfigurieren über die web.xml und die faces-Konfigurationsdateien gab es ganz ungewöhnliche Probleme mit dem Kompilieren bzw. Deployen der Projekte. Vor allen Dingen Projekte, die ich schon zum Laufen gebracht hatte, als auch die generierten Projekte aus den POM-Dateien wurden vielfach nicht übersetzt oder konnten nicht auf den Tomcat depoyed werden. Teils gingen auch die SSI-Dateien mit den Tag-Libs, aber alleine die Existenz einer Java-Datei im Projekt hat die Übersetzung blockiert. Nicht einmal als Bean oder Controller gebaut, sondern eine leere Klasse im source-Verzeichnis hat genügt, um einen Fehler zu erzwingen.
Andere Projektkonfigurationen haben die Java-Controler und -Beans übersetzt, aber die xhtml-Dateien wurden auf dem Server nicht geparst und damit die Tag-Libs nicht verarbeitet.
In Netbeans gab es bei dem Problemen mit dem Java-Code die unverständige Fehlermeldung, dass source in der Version 6 nicht mehr unterstützt wird und wir die Version 7ff nehmen sollten. Nach diversen Problemen habe ich auf mein Matebook als Ursache getippt, aber auf dem Teilnehmerrechner waren die Fehler exakt reproduzierbar.
Irgendwann hatte ich die Faxen dicke und habe auf einem alten Linux-Rechner die Geschichte von Grund auf neu aufgesetzt. Also zuerst Maven, was noch nicht da installiert war, und dann einen Architype für JSF mit der Konsolenanwendung mvn aus dem Internet gezogen. Damit hat die Sache von A bis Z funktioniert und mir ist aufgefallen, dass ich auf dem Linux-Rechner das OpenJDK 8 installiert habe. Auf unseren beiden anderen Rechnern allerdings das JDK 16 und bei meinem Teilnehmer das JDK 15. Und danach haben wir endlich in einer Konfigurationsdatei zu den JSF 2.3 die XML-Tags gefunden, dass die Entwickler- als auch Zieldatei auf Java 8 festgelegt ist.
Unter dem Gesichtspunkt macht auch die Fehlermeldung von Netbeans Sinn – es müsste bei mir eigentlich heißen source in der Version 16, aber das Feld für die Versionsnummer wurde wohl nur einstellig konzipiert. Aus der 16 wurde die 6 und damit eine vollkommen unsinnige Fehlermeldung. Aber zum Zeitpunkt, wo die JSF 2.3 konzipiert wurden, hatte man vermutlich nicht an Inkompatibilitäten in so hohen Folgeversionen, sondern nur älteren Versionen, gedacht. Wir sind nicht so ganz sicher, ob die JSF bis zur Version 2.3 mit den neuen JDK nicht mehr klar kommen, aber ich denke schon. In der Doku steht explizit auch die Version 8. Das deckt sich mit der Tatsache, dass Cordova auch nur bis zur JDK-Version 8 funktioniert. Das habe ich ja in meiner Vorlesung an der TH Bingen die Tage behandeln müssen.
Die JSF werden wohl als Apache MyFaces weiterentwickelt und stehen mittlerweile in der Version 4.0 zur Verfügung, aber die haben wir uns dann nicht mehr genauer angesehen.

Rund um das Thema habe ich auch noch ein paar nützliche Anleitungen gefunden:

JSF Tutorial
https://www.javawebtutor.com/articles/jsf/
https://www.tutorialspoint.com/jsf/jsf_overview.htm

JSF in Tomcat zum Laufen bringen
https://www.byteslounge.com/tutorials/how-to-configure-jsf-in-tomcat-example

Webanwendungen als Docker-Images herstellen
https://jaxenter.de/apache-tomcat-meets-docker-webanwendungen-als-docker-images-herstellen-23213

Grundsätzlich hat sich mein Eindruck gefestigt, dass im Web Java nicht (mehr) der Bringer ist. Irgendwie reihen sich JSF/MyFaces in andere Projekte wie JavaFX/OpenJFX oder auch Cordova ein, bei denen die Originalhersteller die Entwicklung abgetreten haben und wo es aus meiner Sicht nicht sicher ist, dass diese Projekte auf Dauer sich halten und/oder zuverlässig weiterentwickelt werden.

Wobei die Erstellung eines Spring-Microservice für Tomcat wirklich genial einfach war und die mit einer Anleitung erstellte Version des Microservice absolut flexibel und einfach an beliebige Bedürfnisse anzupassen ist.