05.08.2015
Author: Torsten Rademacher

Worauf Du bei einer Liferay-Migration achten solltest

Checkliste

Check 1: Wie viele Individualanpassungen

Checke, ob es viele Individualanpassungen für die alte Version gab und gleichzeitig in der neuen Original-Klasse, JSP, … ebenso viele Änderungen vorgenommen wurden. Du kannst dann davon ausgehen, dass ein sauberes Mergen schwierig wird.

Beachte, dass manch Neues dann sehr schwierig herauszufiltern ist, wenn du dich an denselben Codezeilen vergriffen hast.

Check 2: Neue Portlets

Prüfe, ob es Standard-Portlets gibt, die verschwunden sind oder komplett ersetzt wurden. Der Kalender z.B. ist ab der Version 6.2 ein Zusatzportlet und nicht mehr im ROOT-Verzeichnis. Außerdem arbeitet er mit vollkommen anderen Model-Klassen, was eine Übernahme möglicher vorangehender Individualanpassungen sehr schwer macht.

Die Anpassungen, die für den alten Kalender gemacht wurden, mussten neu geschrieben werden.

Check 3: Veränderte Datenstruktur

Veränderte Datenstrukturen (z.B. bei Kalender, WebContent (Ordner), …)

Bei der Migration von 6.1. auf 6.2 mussten manche Anpassungen quasi neu geschrieben werden, wenn Tabellen und Model/Service-Klassen nicht mehr in ihrer alten Form vorhanden waren. Viele alte Funktionen gaben aufgrund hinzugekommener Mehrsprachigkeit nicht die gewünschten Werte zurück oder waren unbrauchbar. Da Webcontents, bzw. Artikel auch auf Ordner referenzierbar und nicht mehr über eigene Strukturen, sondern mithilfe von „Dynamic Data Mapping“ anpassbar sind, mussten hier einige aufgerufene Prozeduren in den Parametern angepasst werden. Aber die wohl größte Veränderung brachte der Kalender mit sich. Früher eine recht normale Datenbanktabelle, wird er mit Liferay 6.2 über mehrere voneinander abhängige Tabellen abgelegt und mithilfe von auf AJAX basierendem AlloyUI zur Laufzeit erst erzeugt/dargestellt.

Check 4: Zugriff auf Frameworks

AlloyUI hat sich stark geändert. Hier ein kleiner Überblick über Neuerungen in dem von Liferay 6.2 benutzten AlloyUI 2.0. Dies war bei jedem durch uns angepassten Frontend zu spüren. Es tauchten oft Script-Fehler/Fehlfunktionen und wirkungslose CSS-Styles auf.

Check 5: Individuelle Erweiterungen

Kopierte man Standardporlets, um sie individuell anzupassen und gab man ihnen einen andere Namen, wurden sie vom Liferay-Upgrade Prozess ignoriert, da sie diesem nicht bekannt waren.

Lösungsansätze

Problemlösung 1: Konzentration!

Wenn eine Migration ansteht, bei der an der alten Version viele Individualanpassungen vorgenommen wurden und sich in der neuen Liferay-Version viel geändert hat, ist es wichtig, zunächst die von Liferay veränderte Originalversion heranzuziehen. Füge anschließend die Individualanpassungen nach und nach ein. Achte darauf, ob die vorgenommene Änderung überhaupt noch nachgezogen werden müssen oder ob die neue Version sie schon mitbringt.
Zum Beispiel Änderungen bzw. Bugfixes, die auch in Github auffindbar sind und für die neue Version als gefixt erklärt sind.

Problemlösung 2: Stell dem Kunden die neuen Portlets vor

Normalerweise ist die neuere Version eines Portlets auch die bessere und benutzerfreundlichere. Präsentiere diese dem Kunden mal im Rohzustand und nehme Änderungswünsche gesondert an und entwickle ein Konzept. Oft können da weniger Anpassungen ein besseres Produkt hervorbringen.

Problemlösung 3: Bei der Migration an der neuen Version orientieren, nicht die Alte anpassen!

Ändern sich einige Datenstrukturen, so ist es wichtig, dies in den (auch selbst geschriebenen Portlets) zu berücksichtigen. Lediglich in den angepassten Standardportlets nach Problemlösung 1 vorgehen. Handelt es sich um eine Individualentwicklung, sollte vor weiteren Änderungen geprüft werden, ob Java-Klassen oder JSPs von irgendwelchen Liferay-Standards abgeleitet sind. Hier dann die Neuerung der „originalen“ Klasse berücksichtigen und Individualanpassungen entsprechend nachziehen.

Problemlösung 4: Von Anfang an die richtigen Aufrufe an die Frameworks weiterleiten

Der AlloyUI-Dialog z.B. existiert in den neueren Versionen nicht mehr. Dennoch gibt es vor allem in Individualentwicklungen direkte Aufrufe dazu. Dies ist aber nicht nötig! Die meisten AlloyUI-Aufrufe werden von Liferays JS-Files unterstützt. Rufe ich also in diesem Beispiel statt AUI().Dialog(…) Liferay.Util.Window(…) auf, steckt ein und derselbe Aufruf dahinter, im letzteren Fall ist dieser allerdings schon intern auf die neuere Version (AUI().Modal(…)) automatisch migriert.

Problemlösung 5: siehe Lösung 3!

 

Tipps für die Zukunft

Tipp Nr. 1:

Beginnt schon vor der Individualentwicklung: Lerne Liferay kennen. Kenne die Standards, übliche Vorgehensweisen und wie es arbeitet. Halte dich bestmöglich daran.

Tipp Nr. 2:

Verändere so wenig wie möglich! Es gibt unzählige Methoden in Liferay, von denen uns gar nicht bewusst ist, dass sie existieren. Bevor wir selbst eine schreiben, recherchiere, ob diese Funktionalität nicht bereits unterstützt wird. Muss tatsächlich etwas Neues geschrieben werden, schreibe dies in eine eigene Klasse, am besten auch in einem eigenen Package. Diese Trennung macht es übersichtlicher und spätere Anpassungen leichter.

Tipp Nr. 3:

Ist eine Änderung aufgrund eines Bugs nötig, suche zunächst in Github danach! Hier befinden sich bekannte Bugs und deren Lösungen, sofern sie gefixt wurden. Nur wenn hier nichts gefunden wird, eine individuelle Anpassung vornehmen. Aber nie vergessen:

Tipp Nr.4:

Kommentieren! Vor allem angepassten Standardcode mit einer festgelegten Kennzeichnung markieren und bestenfalls auch anmerken, was hier geändert wurde. Das Migrieren auf eine neuere Version fällt viel leichter, wenn erkennbar ist, was aus welchen Gründen geändert wurde. So lassen sich Fehler, Unschönheiten und Redundanzen vermeiden.

Tipp Nr. 5:

Änderung oder Neuentwicklung? Vorher richtig abschätzen. Beispiel Theme: Hier werden vor allem im CSS viele Änderungen vorgenommen. Besonders beim Wechsel auf Liferay 6.2 geschieht das, aber auch stark aus Liferay-Sicht, da ab dieser Version u.a. ein responsives Design unterstützt wird. In fast allen Fällen macht eine Weiterentwicklung des alten Themes keinen Sinn, da zu vieles hinzukommt und zu vieles wegfällt (z.B. sämtliche AlloyUI-Elemente verzichten in der benutzten Version auf das aui-Präfix). Daher: Theme neu auf 6.2 aufsetzen und höchstens für spezielle Styles und Werte das alte als Spickzettel benutzen. Es ist in manchen Fällen aufwändiger das „Alte“ zu erhalten, als etwas Neues zu kreieren.

Zeitaufwand

Der Aufwand verhält sich überproportional zur Komplexität bzw. der Anzahl der Anpassungen im Portal. Je mehr Anpassungen in einer älteren Version vorgenommen wurden, desto schwieriger ist der Aufwand abzuschätzen.

Für eine zuverlässige Schätzung ist es wichtig sowohl das Projekt und vorgenommene Änderungen, als auch die Neuerungen des Portals zu kennen.

Es wirkt sich positiv auf den Gesamtaufwand und die Einhaltung der Schätzung aus, wenn zuvor eine saubere Recherche vorgenommen wurde, dieses Wissen ausgetauscht wurde und dann mit klarer Struktur ein Plan erstellt wird.

Da hier das gesamte Portal betroffen ist und die Komplexität ohne ausreichende Recherche sehr schwer abzuschätzen ist, ist es wichtig, ein von den laufenden Systemen unabhängiges Testsystem einzurichten und sich bereits am Anfang einen großen Puffer zu schaffen. Lieber zu viel schätzen – Mit hoher Wahrscheinlichkeit werden unvorhergesehene Probleme auftauchen.

Vorgehensweise

Nach welchem Modell sollte das Projekt „Liferay Migration“ organisiert sein?

Eine Planung ist zwar sehr wichtig, dennoch würde ich aufgrund zu vieler unerwarteter Schwierigkeiten im Entwicklungsprozess von zu statischen Vorgehensweisen im gesamten wie z.B. dem V-Modell oder dem Wasserfallmodell abraten. Ein iterativer Ansatz wäre hier schon deutlich besser, da man hier zur Not auch ohne immensen Mehraufwand gegensteuern kann. Da die Planung aber zu den wichtigsten Faktoren der Einhaltung des geschätzten Aufwandes zählt, wäre auf der anderen Seite ein rein agiler Ansatz ebenso kontraproduktiv, da sich das Projekt ohne rechtzeitige Kommunikation in die Länge ziehen kann. Ein Modellwechsel innerhalb des Entwicklungsprozesses kann hier auch, wenn sinnvoll und von Anfang an angekündigt, eingesetzt werden. Der Zeitpunkt des Wechsels könnte z.B. nach Pareto (80:20) erfolgen: Der erste Teil, in dem zunächst die Lauffähigkeit hergestellt werden soll ist planungsintensiv. Umso wichtiger ist er aber für spätere kleinere Anpassungen. Zudem bringt dieser Teil den größten Nutzen. Da er wenig Entwicklungszeit beansprucht, könnte hier ein statisches, planungsintensiveres Modell verwendet werden. Mit einem gut strukturierten Plan wäre in dieser Phase sogar eine Umsetzung nach dem Wasserfallmodell denkbar. Läuft erst mal diese Version „0.9“ – also eine vorübergehend stabile und an den wichtigsten Stellen aktualisierte Testversion , werden die Individualanforderungen gesammelt und entsprechend umgesetzt. Hier handelt es sich eher um „Semantik“ statt Funktionalität. Darum können hier auch deutlich kleinere Pakete geschnürt werden. Ab diesem Zeitpunkt sollte daher auf eine agilere Methodik wie z.B. Scrum gewechselt werden. Ab jetzt ist es sinnvoll regelmäßig die Neuerungen auszuliefern (Prototyping), bis das Ziel erreicht ist.

Vergleich mit leichterer Migration

Dass sich der Aufwand überproportional zur Anzahl der Änderungen verhält, wurde festgestellt, als 2 Projekte migriert wurden, von denen eines nur wenig, das andere extrem angepasst wurde. Was das zweite Projekt deutlich vereinfachte, waren:

  1. Sehr wenige Anpassungen des Liferay-Standards, somit wenig Vergleichsarbeit, eher Individualanpassungen kontrollieren.
  2. Kombination mit einem kleinen Relaunch: Da im Frontend vieles durch die Migration verändert werden sollte, war von Anfang an klar, dass beim Theme auf eine Neuentwicklung gesetzt wird
  3. Keine zu migrierenden WebContent-Strukturen. Von 6.1 auf 6.2 werden JournalStructures zu DDMStructures (DynamicDataMapping). Diese sind zwar vom grundlegenden Aufbau sehr ähnlich bis gleich, verursachen aber beim Migrieren Probleme aufgrund z.B. fehlender Mehrsprachigkeit, fehlerhafter Formatierung, ...
  4. Erfahrung: Da mit diesem kleineren Projekt später angefangen wurde, konnte man bereits aus Fehlern der ersten Migration lernen und so Probleme und deren Ursachen schneller erkennen und beseitigen.