Tech Blog

Override LPKG

Come applicare fix a Liferay utilizzando l'override dell'LPKG

Antonio Musarra
Software Architect
4 minuti di lettura
liferay, lpkg e openjdk
Questo articolo è disponibile anche in English 🇬🇧

Qualche giorno addietro ho avuto la felice idea di aggiornare la versione di OpenJDK dalla 11.0.5 alla 11.0.6. Sembrava che tutto filasse per il verso giusto ma sono stato colpito dal famoso proverbio

Non lasciare la vecchia strada per quella nuova

All’avvio di Liferay Portal 7.2 GA2 CE eccoti apparire l'errore abbastanza odioso indicato a seguire (in console 1).

Caused by: org.apache.jasper.JasperException: PWC6033: Error in Javac compilation for JSP
	at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:655)
	at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:375)
	at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:473)
	at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:377)
	at org.eclipse.equinox.http.servlet.internal.servlet.RequestDispatcherAdaptor.include(RequestDispatcherAdaptor.java:48)
	at deployment.ROOT.war//com.liferay.portlet.internal.PortletRequestDispatcherImpl.dispatch(PortletRequestDispatcherImpl.java:291)
	... 165 more
Caused by: java.lang.RuntimeException: java.lang.NullPointerException: entry
Console 1 - Estratto errore PWC6033 per compilazione JSP

Dopo qualche mirata ricerca ho scoperto che l'errore è dovuto ad un bug (ancora aperto) sulla OpenJDK 11.0.6 JDK-8237875 (zipfs) DirectoryStream entries changed behavior between JDK 11.0.5 and JDK 11.0.6

Liferay dal canto suo ha provveduto a risolvere, anche velocemente, tramite LPS-107983 - OpenJDK 11.0.6 compatibility problem. Questa LPS risulta già chiusa e risolve il problema sul branch 7.x e master.

Come possiamo applicare la patch dell'LPS senza aspettare l'uscita della nuova GA?

Le possibili soluzioni sono:

  1. Downgrade di OpenJDK alla versione 11.0.5;
  2. Se disponiamo della DXP siamo nelle condizioni di richiedere supporto direttamente a Liferay;
  3. Se disponiamo della CE possiamo applicare la patch in modo autonomo.

La prima strada non è sempre percorribile a causa del fatto che il più delle volte l’aggiornamento della JDK rientra tra uno di quei componenti il cui aggiornamento è centralizzato e abbiamo per cui poco spazio di manovra.

La seconda strada è semplice da percorre e solitamente in pochi giorni si ottiene la Hot Fix.

Per non farci mancare nulla, direi di scegliere la terza strada, che poi è quella più interessante.

1. Come applicare la patch

Vediamo come sia possibile e semplice applicare la patch a Liferay Portal CE. La versione di riferimento è Liferay Portale CE 7.2.1 GA2.

Come possiamo applicare la nostra Hot Fix anche sulla CE? La risposta è davvero semplice: Overriding lpkg files.

Il bundle a cui dobbiamo applicare la patch 84189 è Liferay Portal OSGi Web Servlet JSP Compiler (com.liferay.portal.osgi.web.servlet.jsp.compiler) che fa parte dell’LPKG Liferay CE Static - Impl.lpkg. In questo caso possiamo quindi applicare l’Overriding lpkg files, anche a quelli Static.

La procedura da seguire è:

  1. Creare il bundle in formato jar contenente la patch;
  2. Il nome del bundle deve essere uguale all'originale, meno le informazioni sulla versione;
  3. Copiare il file .jar del bundle nella cartella $LIFERAY_HOME/osgi/static;
  4. Rimuovere del contenuto della directory $LIFERAY_HOME/osgi/state;
  5. Avviare Liferay Portal. Notare che ogni volta che si aggiungono e rimuovono .jars in questo modo, è necessario chiudere e riavviare Liferay Portal per rendere effettive le modifiche.

Se è necessario ripristinare le personalizzazioni, eliminare i file .jar di sostituzione: Liferay Portal utilizzerà il file .jar originale al successivo avvio.

Sembra tutto molto chiaro!

Come facciamo a creare il nuovo bundle che conterrà la patch dell’LPS-107983? Lo vedremo nel prossimo capitolo.

2. Come creare il bundle con la patch

Per creare il nuovo bundle sono necessari i sorgenti e per ottenerli esistono essenzialmente due modi che sono:

  1. Clone dei sorgenti di Liferay Portal 7.2.1 GA1 dal repository GitHub;
  2. Ottenere i sorgenti dal repository Maven com.liferay.portal.osgi.web.servlet.jsp.compiler versione 4.0.14.

La scelta della prima strada potrebbe richiedere parecchio tempo per via del clone del repository che anche se eseguito con l’opzione --depth 1 richiede del tempo.

Personalmente ho scelto la seconda strada, che in pochi minuti ci consentirà di ottenere il bundle con la patch. A seguire tutti gli step necessari (e non serve nessun IDE). Ecco l'elenco dei macro task:

  1. Creazione di un Liferay Workspace via blade;
  2. Creazione della struttura di directory per il modulo portal-osgi-web-servlet-jsp-compiler;
  3. Copiare dei sorgenti dal bundle jar scaricato dal repository Maven all’interno del modulo su Liferay Workspace;
  4. Scaricare il bnd.bnd dal repository GitHub di Liferay e posizionarlo sulla root del modulo;
  5. Scaricare il build.gradle dal repository GitHub di Liferay e posizionarlo sulla root del modulo;
  6. Modificare il build.gradle per aggiungere FileUtil (com.liferay.gradle.util.FileUtil);
  7. Applicare la patch 84189;
  8. Eseguire la build del modulo;
  9. Accertarsi che il portale sia spento;
  10. Installare il modulo in $LIFERAY_HOME/osgi/static;
  11. Avviare il portale.

Il set di comandi mostrati a seguire realizzano i punti da 1 a 5. Se volete risparmiare anche questo tempo, allora potete attingere direttamente al repository che ho predisposto ad hoc https://github.com/smclab/apply-lps-107983-openjdk-11-0-6

$ mkdir ~/apply-lps-107983-openjdk-11-0-6
$ cd ~/apply-lps-107983-openjdk-11-0-6
$ blade init -v 7.2
$ mkdir modules/apps/static/portal-osgi-web/portal-osgi-web-servlet-jsp-compiler
$ mkdir -p src/main/java
$ mkdir -p src/main/resources
$ cd src/main/java
$ curl https://repo1.maven.org/maven2/com/liferay/com.liferay.portal.osgi.web.servlet.jsp.compiler/4.0.14/com.liferay.portal.osgi.web.servlet.jsp.compiler-4.0.14-sources.jar | jar xv
$ rm -rf META-INF/
$ mv javax ../resources
$ curl -L -O https://github.com/liferay/liferay-portal/raw/7.2.1-ga2/modules/apps/static/portal-osgi-web/portal-osgi-web-servlet-jsp-compiler/bnd.bnd
$ curl -L -O build.gradle https://github.com/liferay/liferay-portal/raw/7.2.1-ga2/modules/apps/static/portal-osgi-web/portal-osgi-web-servlet-jsp-compiler/build.gradle
Console 2 - Step necessari per prepare il bundle con la patch

Il punto 6 richiede la modifica del file build.gradle, questo è necessario affinché non otteniate l’errore mostrato a seguire.

Could not compile build file '/Users/antoniomusarra/Progetti/MyProjects/Liferay/sources/apply-lps-107983-openjdk-11-0-6/modules/apps/static/portal-osgi-web/portal-osgi-web-servlet-jsp-compiler/build.gradle'.
> startup failed:
  build file '/Users/antoniomusarra/Progetti/MyProjects/Liferay/sources/apply-lps-107983-openjdk-11-0-6/modules/apps/static/portal-osgi-web/portal-osgi-web-servlet-jsp-compiler/build.gradle': 1: unable to resolve class com.liferay.gradle.util.FileUtil
   @ line 1, column 1.
     import com.liferay.gradle.util.FileUtil
     ^
Console 3 - Errore di compilazione prima della modifica del build.gradle

Per evitare l’errore occorre aggiungere sul file build.gradle il contenuto mostrato a seguire.

buildscript {
   dependencies {
      classpath group: "com.liferay", name: "com.liferay.gradle.util", version: "1.0.36"
   }

   repositories {
      maven {
         url "https://repository-cdn.liferay.com/nexus/content/groups/public"
      }
   }
}
Listato 1 - Modifica del build.gradle per aggiungere la dipendenza richiesta

A questo punto siamo nelle condizioni di poter applicare la patch nel seguente modo.

$ cd ~/apply-lps-107983-openjdk-11-0-6
$ curl -O https://patch-diff.githubusercontent.com/raw/brianchandotcom/liferay-portal/pull/84189.patch
$ git apply --verbose 84189.patch
Console 4 - Applicazione della patch ai sorgenti Liferay del bundle affetto dal bug

Se tutto va come deve, dovreste vedere un output simile a quello mostrato nella figura seguente.

Figura 1 - Applicazione patch ai sorgenti Liferay del bundle affetto dal bug
Figura 1 - Applicazione patch ai sorgenti Liferay del bundle affetto dal bug

Una volta applicate possiamo procedere con la build del bundle utilizzando il classico comando build

$ ./gradlew build
Console 5 - Build del bundle

A portale spento, copiamo il nuovo bundle (senza la versione) all’interno della directory $LIFERAY_HOME/osgi/static/

$ cp modules/apps/static/portal-osgi-web/portal-osgi-web-servlet-jsp-compiler/build/libs/com.liferay.portal.osgi.web.servlet.jsp.compiler-4.0.14.jar /Users/antoniomusarra/dev/liferay/liferay-ce-portal-7.2.1-ga2-wildfly-16/osgi/static/com.liferay.portal.osgi.web.servlet.jsp.compiler.jar
Console 6 - Copia del bundle con la patch in $LIFERAY_HOME/osgi/static/

A questo punto, dopo aver eliminato il contenuto della directory $LIFERAY_HOME/osgi/state, avviamo il portale. Fate attenzione ai log di Liferay perchè dovreste vedere le seguenti righe di log che indicano l’avvenuta installazione del nuovo bundle che va in override all’esistente.

2020-03-24 22:17:48.836 INFO  [ServerService Thread Pool -- 73][ModuleFrameworkImpl:1468] Starting initial bundles
2020-03-24 22:17:49.234 INFO  [ServerService Thread Pool -- 73][ModuleFrameworkImpl:952] /Users/antoniomusarra/dev/liferay/liferay-ce-portal-7.2.1-ga2-wildfly-16/osgi/marketplace/Liferay CE Static - Impl.lpkg:com.liferay.portal.osgi.web.servlet.jsp.compiler-4.0.13.jar is overridden by /Users/antoniomusarra/dev/liferay/liferay-ce-portal-7.2.1-ga2-wildfly-16/osgi/static/com.liferay.portal.osgi.web.servlet.jsp.compiler.jar
Log 1 - Log di start-up di Liferay con evidenza dell'operazione di override del bundle

Appena il portale è in piedi, eseguite il deploy di una qualunque portlet MVC e verificate di non ottenere più errori di compilazione sulle JSP. Le figure a seguire mostrano la home page del portale Liferay prima e dopo l’installazione del bundle con la patch.

Figura 2 - Portlet in errore prima senza la patch
Figura 2 - Portlet in errore prima senza la patch
Figura 3 - Portlet funzionante dopo l'installazione del bundle con la patch
Figura 3 - Portlet funzionante dopo l'installazione del bundle con la patch

In questi casi, quando andiamo a fare il patch di componenti Liferay, è consigliabile metterlo in evidenza, per esempio con opportuna indicazione sul Bundle Name.

g! lb com.liferay.portal.osgi.web.servlet.jsp.compiler
START LEVEL 20
   ID|State      |Level|Name
    1|Active     |    6|Liferay Portal OSGi Web Servlet JSP Compiler (SMC - PATCHED-1) (4.0.14)|4.0.14
g!
Console 7 - Accesso alla Gogo Shell e verifica del nuovo bundle installato

Benissimo! Adesso abbiamo il nostro Portale Liferay 7.2 GA2 che funziona con OpenJDK 11.0.6

3. Conclusioni

In questo articolo abbiamo visto come sia semplice applicare una patch ad un componente core di Liferay senza la necessità di attendere la prossima release. Tutto questo è reso possibile per tre semplici motivi:

  1. Liferay è Open Source;
  2. Liferay dalla versione 7.0 ha adottato in toto OSGi, ergo, il benvenuto alla modularità;
  3. Liferay ha sviluppato in set di framework che ne facilitano l'estensione, anche dei componenti core del portale.

Prima di buttare la spugna quanto incontrate un problema che potrebbe sembrare insormontabile, vi consiglio sempre di consultare la documentazione di Liferay dove nella maggior parte dei potreste trovare la soluzione al vostro problema.

scritto da
Antonio Musarra
Software Architect
In SMC ricopre il ruolo di Senior Software Architect e si occupa in genere di consulenze specialistiche su progetti che riguardano la piattaforma Liferay, curando in particolare gli aspetti d'integrazione con altri sistemi. Crede nella condivisione della conoscenza come mezzo per la crescita personale e per questo motivo, circa otto anni fa, ha creato un suo blog personale: Antonio Musarra's Blog www.dontesta.it. Con la voglia ancora di condividere, ha pubblicato su Amazon nel 2015 il suo primo eBook, Sviluppo Liferay con Maven, arrivando alla sua ultima pubblicazione del 2018 con l'eBook Liferay Portal Security Audit.

Potrebbero interessarti anche…