Preparing for upgrading to Jahia 8.2

May 31, 2024

Jahia 8.2 is a feature release with a strong focus on addressing technical debt and upgrading libraries.

All changes in Jahia 8.2.0 (including changes to libraries and modules versions) are listed in the Jahia 8.2.0 Release Notes, we strongly encourage you to review this page.

While we are confident the impact on your modules should be very limited, this document contains technical details and step-by-step procedures to help prepare and validate your upgrade. 

Updates to Jahia supported stack

For this release, Jahia revised its supported stack, you're invited to review the dedicated page on the academy and make sure your environment complies with the supported stack. Jahia also extended support to newer versions of its dependencies, so it's also a good opportunity for you to update some components of your existing platform.

In hindsight, the following changes were made:

  • Support for JDK8 was dropped, and support for JDK 17 was added
  • Support for databases versions was updated (please refer to the support stack page)

Content Editor merged into jContent

Content Editor module merged into jContent

Jahia 8.0 and 8.1 included two modules: Content Editor and jContent. The Content Editor module offered a form interface for creating and editing content, while the jContent module provided the interface for managing content and media.

Starting from Jahia 8.2.0, these two modules have been merged into a single module called jContent 3.0. This new version of jContent includes the functionalities of the jContent 2x module, allowing users to manage contents and media and also includes the new version of Page Composer and the functionalities of the Content Editor module.

Updates to JSON Overrides

As part of this merge of Content Editor and jContent, we have simplified the way one can customize Content Editor forms for a given nodetype, by relying on a single json override file only, instead of two (currently part of the override is done in META-INF/jahia-content-editor-forms/fieldsets, and part of the other is done in META-INF/jahia-content-editor-forms/forms). This change is meant to simplify creation of json override files, and to provide more flexibility when moving fields and fieldset in the edition form.

We were able to keep compatibility with the previous JSON override files, with the exception of the target properties defined in META-INF/jahia-content-editor-forms/fieldsets to move fieldset and fields in different location of the form: such “move” will need to be done in META-INF/jahia-content-editor-forms/forms. 

Some jContent / Content Editor custom extensions may require a code update

As part of the work done in jContent and Content Editor, we have made some changes that may impact custom jContent and Content Editor extensions, which:

  • Declare custom accordions in jContent, and custom accordions for the CE pickers (as documented in the “Create accordions” documentation
  • Use the jContent content tables
  • Or rely on the current path stored in redux

Customers who may have developed such custom extensions (for instance a custom property selector for Content Editor) will most likely have to adjust their code.

Libraries upgrade and removal

The following librairies were updated between Jahia 8.1.7.1 and Jahia 8.2.0

Library Version in Jahia 8.1.7.1 Version in Jahia 8.2.0.1
Apache Commons Collections 3.2.2 3.2.2-jahia
Apache Commons Compress 1.21.0 1.25.0
Apache Commons Ognl 3.2.21 Removed
Apache Commons IO 2.11.0 2.13.0
Apache Felix Configadmin 1.9.16 1.9.26
Apache Felix Fileinstall 3.6.4-jahia3 3.7.4-jahia1
Apache Felix Framework   6.0.5
Apache Felix Metatype 1.2.2 1.2.4
Apache Felix Utils 1.11.2 1.11.8
Apache Felix Web Console 4.3.16-jahia2 4.3.16-jahia3
Apache Jackrabbit 2.18.4-jahia1 2.20.12-jahia1
Apache Jackrabbit Oak API   1.48.0
Apache Karaf 4.2.7 4.3.10
Spring 5 feature have been removed. Can be installed manually if required
Apache Maven Dependency Plugin 2.8 3.6.0
Apache Maven Deploy Plugin 2.8.2 3.1.0
Apache Maven Install Plugin 2.5.2 3.1.0
Apache Maven Jar Plugin 2.6 3.3.0
Apache Maven Javadoc Plugin 2.10.4 3.6.3
Apache Maven Resources Plugin 2.6 3.3.1
Apache Maven SCM Plugin   2.0.1
Apache Portals Portlet API 1.0 Removed
Apache Portals Pluto Libraries 2.0.2 Removed
Apache Shiro 1.10.0 1.13.0
Not exposed anymore
Apache Tika 1.28.5 2.9.1
Apache Tomcat 9.0.83 9.0.85
Apache Maven Compiler Plugin 3.7.0 3.11.0
Graphql-java Dataloader   3.2.0
DB Driver - MariaDB 3.0.9 3.3.3
DB Driver - MySQL 8.0.33 8.3.0
DB Driver - MSSQL 9.4.1.jre8 12.6.1.jre11
DB Driver - Oracle 21.9.0.0 21.13.0.0
DB Driver - PostgreSQL 42.6.0 42.6.1
OWASP Dependency Check Plugin 8.2.1 9.0.9
Dom4j 1.6.1 2.1.4
Drools 6.0.0.Final 6.0.0.Final-jahia1
Eclipse JDT    3.33.0
Eclipse JDT Core Compiler 4.6.1 Removed
EHCache 2.8.5 2.10.9.2
Google Kaptcha 2.3 Removed
GraalVM   22.3.3
GraphQL Java 13.0 21.3
GraphQL Java Annotations 7.2.1 21.1
GraphQL Java Extended Scalars   21.0
GraphQL Java Servlet 9.1.0 15.1.1-jahia
Guava 30.1.1-jre 33.0.0-jre
Hazelcast 3.12.10 3.12.13
Hibernate ORM 5.5.3.Final 5.5.3.Final
Not exposed anymore
Izpack 4.3.5-jahia11 4.3.5-jahia12
Jackson Libraries 2.14.2 2.15.2
Jahia Plugin 6.8 6.10
Jansi 1.18 2.4.0
Javax XML Bind 2.3.1 Removed
Javax Mail 1.6.1 1.6.2
Javax Portlet API 2.0 Removed
jdom & jdom2 1.1.3 2.0.6.1
JGroups 3.4.8.Final 3.6.20.Final
JQuery 3.4.1 3.7.1
Json 20070829 20232013
Felix Maven Bundle Plugin 5.1.2 5.1.9
Mvel2 2.1.7 2.1.7.Jahia1
OSGi 6.0.0 7.0.0
Pax Logging 1.11.13 2.2.3
Pax URL 2.6.1 2.6.14
Pax Web API 7.3.7 7.3.29
Pax Web JSP 7.3.7 7.3.29-jahia1
Rome 1.0 Removed
Sonar Scanner for Maven Plugin 3.9.1.2184 3.10.0.2594
Spring Beans 3.2.18.jahia1_OSGI 3.2.18.jahia2_OSGI
Spring Web 3.2.18.RELEASE_OSGI 3.2.18.jahia4_OSGI
SnakeYaml 1.33.0 2.2.0
Apache Xalan 2.7.2 2.7.3
Yahoo YUI Compressor 2.4.9-20161014 Removed

 

Begin by identifying which of your modules are using libraries listed above. Then, depending on the change, a recompilation may be sufficient, otherwise a refactoring may be needed (for instance if your module relies on a removed library).

Changes to Jahia distribution and modules


Modules removed from Jahia distribution

The following modules previously present are not available by default when starting a Jahia 8.2.0.1. They can be installed independently.

Module Support status
channels Community
default-skins Community
grid Community
jahia-category-manager Community
sdl-generator-tools Community
skins Supported
tabularList Community

More details about changes to module statuses can be found on this Academy page.

Updates to the default module

Content types listed below were removed from the "default" module and moved to legacy-default-components.

The legacy-default-component is a supported module currently included in Jahia 8.2.0.1, you can be in either of these two situations:

  • If you are NOT using these content types at all (directly or through inheritance): simply undeploy the legacy default components module.
  • If you are using one of  the content types, simply activate the module on all websites where they are required

Content types moved to the legacy-default-components module:

[jmix:columns] 
[jmix:gadget] 
[jmix:glossary]
[jmix:listOrdered] 
[jmix:portletContent] 
[jmix:userFilterable] 
[jnt:addComment] 
[jnt:addContent] 
[jnt:authorDisplay]
[jnt:backToParentPage] 
[jnt:banner]
[jnt:categorizing] 
 
[jnt:commentsList]
[jnt:createWebProject]  
[jnt:currentUserDisplay]
[jnt:displayCategories] 
[jnt:displayCurrentLanguage]
[jnt:displayMetadata] 
[jnt:fileList]
[jnt:flash]
[jnt:frame]
[jnt:gotoAdmin] 
[jnt:gotoContribute]  
[jnt:gotoEdit]  
 [jnt:gotoManager]
[jnt:gotoStudio]  
[jnt:introduction]
[jnt:languageSwitcher] 
[jnt:listSites] 
[jnt:login]
[jnt:loginForm]
[jnt:logout]
[jnt:mainContent]
[jnt:modeDispatcher]
[jnt:openInPopup] 
[jnt:pageBreadcrumb]
[jnt:pageFormCreation]
jmix:formContent 
[jnt:pager] 
[jnt:pageTitle]
[jnt:portletReference]
[jnt:shortcuts]
[jnt:siblingNavigation]
[jnt:siteLink]  
[jnt:toggleMobileDisplay] 
[jnt:tree] 
[jnt:video] 
[jnt:workflowMonitor] 

jExperience compatibility

Jahia 8.2.0.1 is not compatible with jExperience 2 (and jCustomer 1), before upgrading to Jahia 8.2.0.0, it is required to first upgrade to the latest version of jExperience 3 (and jCustomer 2).

Depending on your environment, the upgrade to jExperience 3, might be complex. It is documented on this page of the academy. If you are running jExperience 2 (with jCustomer 1) and Jahia 81x, make sure to review jExperience 3 migration guide.

Catalina and JDK options

We regularly update the CATALINA_OPTS and JDK_JAVA_OPTIONS variables in our Jahia releases, these changes are automatically applied when installing Jahia via our Installer, when using our Docker images or when using Jahia Cloud.

But if you are installing Jahia by another method, we provide below the settings we currently use and recommend for Jahia environments:

CATALINA_OPTS="$CATALINA_OPTS -server -Xms$JAHIA_JAVA_XMS -Xmx$JAHIA_JAVA_XMX -Djava.awt.headless=true -verbose:gc -Djava.net.preferIPv4Stack=true -Djavax.el.class-resolution.disableOnLowerCase=true"

# GC setup
CATALINA_OPTS="$CATALINA_OPTS -XX:+UseG1GC -XX:+DisableExplicitGC -XX:+UseStringDeduplication -XX:MaxTenuringThreshold=7"
CATALINA_OPTS="$CATALINA_OPTS -XX:+ParallelRefProcEnabled -XshowSettings:vm -XX:+UnlockDiagnosticVMOptions "
CATALINA_OPTS="$CATALINA_OPTS -XX:GuaranteedSafepointInterval=0 -XX:-UseBiasedLocking -XX:+UseCountedLoopSafepoints -XX:LoopStripMiningIter=100"
CATALINA_OPTS="$CATALINA_OPTS -XX:+SafepointTimeout -XX:SafepointTimeoutDelay=1000"

# Log/debug info
CATALINA_OPTS="$CATALINA_OPTS -Xlog:gc*,gc+ref=debug,gc+heap=debug,gc+age=trace:file=gc-%p-%t.log:tags,uptime,time,level:filecount=10,filesize=20m"
CATALINA_OPTS="$CATALINA_OPTS -Xlog:os+container=debug,pagesize=debug:file=os-container-pagesize-%p-%t.log:tags,uptime,time,level:filecount=10,filesize=20m"
CATALINA_OPTS="$CATALINA_OPTS -Xlog:safepoint*:file=safepoints-%p-%t.log:tags,uptime,time,level:filecount=10,filesize=20m"
CATALINA_OPTS="$CATALINA_OPTS -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintConcurrentLocks"
CATALINA_OPTS="$CATALINA_OPTS $JAHIA_JAVA_OPTS"

CATALINA_OPTS="$CATALINA_OPTS -Dderby.system.home=%{derby.home.unix}"
CATALINA_OPTS="$CATALINA_OPTS -Dkaraf.handle.sigterm=false"
CATALINA_OPTS="$CATALINA_OPTS -Dlog4j2.formatMsgNoLookups=true"

# The following section is required for installing Distributed-sessions 3.5.0+
CATALINA_OPTS="$CATALINA_OPTS -Djavax.xml.validation.SchemaFactory:http://www.w3.org/2001/XMLSchema=com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory -Djavax.xml.transform.TransformerFactory=com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl"

export JDK_JAVA_OPTIONS="$JDK_JAVA_OPTIONS --add-opens=java.base/java.net=ALL-UNNAMED --add-exports org.graalvm.truffle/com.oracle.truffle.api.nodes=ALL-UNNAMED --add-exports org.graalvm.truffle/com.oracle.truffle.api.instrumentation=ALL-UNNAMED --add-exports org.graalvm.truffle/com.oracle.truffle.api.dsl=ALL-UNNAMED --add-exports org.graalvm.truffle/com.oracle.truffle.api=ALL-UNNAMED --add-exports org.graalvm.truffle/com.oracle.truffle.api.exception=ALL-UNNAMED --add-exports org.graalvm.truffle/com.oracle.truffle.api.frame=ALL-UNNAMED --add-exports org.graalvm.truffle/com.oracle.truffle.api.object=ALL-UNNAMED --add-exports org.graalvm.truffle/com.oracle.truffle.api.interop=ALL-UNNAMED --add-exports org.graalvm.truffle/com.oracle.truffle.api.strings=ALL-UNNAMED --add-exports org.graalvm.truffle/com.oracle.truffle.api.library=ALL-UNNAMED"

 

Step 1: Explicitly declare dependencies (recommendation)

This section serves as a reminder and is not directly related to the upgrade to Jahia 8.2.0.0, it is recommended to explicitly declare your dependencies instead of automagically relying on dependencies exposed by the core or other modules.

A dedicated page on the academy details these best practices.

Your pom.xml file should contain all but only the modules your codebase depends on (no more, no less, with a defined version range).
 

Step 2: Review Alternatives for removed or deprecated libraries

Some libraries, detailed in this section, were removed from Jahia 8.2.0.0 and cannot be imported separately in your module. If you are currently relying on these libraries, this section of the document provides pointers to updating your codebase to use alternative solutions.

Hibernate

One of the biggest changes is the change around Hibernate, which has been removed for use in modules. Instead, JDBC is used directly. To have access to datasource you can get a reference of corresponding OSGI service and use it directly in your providers. Here’s an example of what it might look like: 

<osgi:reference id="osgiDS" interface="javax.sql.DataSource" filter="(osgi.jndi.service.name=jdbc/jahia)"/>

and then the service can be used like so: 

<bean id="ProviderInitializerService" class="org.jahia.modules.external.id.ExternalProviderInitializerServiceImpl">
        <property name="datasource" ref="osgiDS"/>
...
</bean>

This also means that querying against the database will need to be done via connection through the new datasource, which may mean rewriting some code if you were relying on hibernate ORM.

You may also need to rely on different annotations and replace org.hibernate.validator with javax.validation as an example.

import javax.validation.constraints.NotEmpty;

An alternative can be to provide Hibernate in your module. You’ll have to do the full initialization with the datasource.

Alternative to Spring events

A new alternative has been developed to Spring events. A simple event service and event listener have been added for sending and receiving synchronous events. Login and logout events are now sent using the new service. 

LoginEvent event = new LoginEvent(this, jahiaUser, authContext);
                SpringContextSingleton.getInstance().publishEvent(event);
                ((JahiaEventService) SpringContextSingleton.getBean("jahiaEventService")).publishEvent(event);

A test module has been added to OSGi-modules-samples to test the new listener.

Spring Deprecation

The usage of Spring in your modules is now deprecated, and although Spring 3 has not been removed from Jahia 8.2, we identified a few use cases in which a small refactoring of your code might be necessary for your module to be compatible with Jahia 8.2

To identify if you are impacted, deploy your module as usual on Jahia 8.2, and look for the following error:

ASM ClassReader failed to parse class file - probably due to a new Java class file version that isn't supported yet.

These errors will be triggered by classes in your module extending a Jahia class (such as bstractFilter, AbstractServletFilter, Action, StaticAssetMapping, DefaultEventListener, ...) and that also use Spring Annotations (@Component, @Autowired, @Activate ...).

You can easily look for these classes using the following command:

grep -r  “import org.springframework.stereotype”

For example, the following class is impacted by the spring deprecation:

package org.foo;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class CustomServletFilter extends AbstractServletFilter implements InitializingBean {

   @Autowired
   private JCRTemplate jcrTemplate;

   @Override
   public void afterPropertiesSet() throws Exception {
  	//DO some init stuff
   }

   @Override
   public void destroy() {
   }

   @Override
   public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
   	LOGGER.info("CustomServletFilter");
   }
}

If your module is impacted by the Spring deprecation, the following next steps are available for your module:

  • Migrate from Spring to OSGI (recommended)
  • Continue using Spring (note that it will be completely removed in future releases)

Option 1: Migration from Spring to OSGI

In this option, you will stop using any kinds of spring annotations or classes and use the corresponding OSGI ones.

Taking the example shown above, the migrated class would look like this:

package org.foo;

import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;

@Component(immediate = true, service = AbstractServletFilter.class)
public class CustomServletFilter extends AbstractServletFilter {

   private JCRTemplate jcrTemplate;

   @Reference
   public void setJCRTemplate(JCRTemplate jcrTemplate) {
  	this.jcrTemplate = jcrTemplate;
   }

   @Activate
   public void onActivate() {
   	//DO some init stuff
   }

   @Override
   public void destroy() {
   }

   @Override
   public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
  	LOGGER.info("CustomServletFilter");
   }
}

During this migration, pay special attention to the following points:

  • we used the @Component annotation of OSGI, specific documentation can be found on the Academy here and here.
  • we have declared it as a service of type AbstractServletFilter in the annotations parameters
  • we don't implement Spring InitializedBean interface anymore
  • we have replaced the @Autowire spring annotation with an OSGI @Reference. Note that you can only reference components that are exposed in OSGI. You can check such exposition using the Jahia tools interface and looking in the OSGI > Service section.
  • we use the @Activate annotation of OSGI to replace the behavior of the afterPropertiesSet implemented from the Spring InitializedBean interface

You will find many samples in the dedicated github project: https://github.com/Jahia/OSGi-modules-samples.

Option 2: Continue using Spring

If you want to continue using Spring, you will first need to compile your module using a java target version 8. Spring version included in Jahia 8.2 is not able to introspect compiled classes in a Java version prior to 8.

<properties>
	<maven.compiler.release>8</maven.compiler.release>
</properties>

You will also need to remove all Spring annotations on classes extending Jahia Abstract Classes (Jahia 8.2 is compiled using Java 11 and is not compatible with Spring annotations). Then you need to use a classic spring bean configuration in a spring context file. Injection should then be done using the spring context file using constructor parameters or dedicated setters.

Taking the example shown above, the migrated class would look like this:

package org.foo;

import org.springframework.beans.factory.InitializingBean;

public class CustomServletFilter extends AbstractServletFilter implements InitializingBean {

   private JCRTemplate jcrTemplate;

   public void setJCRTemplate(JCRTemplate jcrTemplate) {
  	this.jcrTemplate = jcrTemplate;
   }

   public void onActivate() {
   	//Do some init stuff
   }

   @Override
   public void destroy() {
   }

   @Override
   public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
  	LOGGER.info("CustomServletFilter");
   }
}

Thus a classical Spring applicationContext file can be used: 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    
    <bean id="customServletFilter" class="org.foo.CustomServletFilter" init-method="onActivate">
   	<property name="jcrTemplate" ref="jcrTemplate"/>
    </bean>
</beans>

During this migration, pay special attention to the following points:

  • we have removed all spring annotations
  • we have added a setter for the JCRTemplate
  • we used a classic xml bean declaration file with the JCRTemplate bean
  • we have specified a init-method parameter for our bean to replace the @Activate annotation

Step 3: Update Jahia Parent and Jahia Plugin

Although alternatives are available (see this KB Entry), we recommend updating the jahia-parent version in your modules to Jahia 8.2.0.1

In your pom.xml, set the parent version to Jahia 8.2.0.1 and update jahia.plugin.version to 6.9

[...]
<parent>
    <groupId>org.jahia.modules</groupId>
    <artifactId>jahia-modules</artifactId>
    <version>8.2.0.1</version>
</parent>
[...]
<properties>
    [...]
    <jahia.plugin.version>6.9</jahia.plugin.version>
</properties>
[...]

In your pom.xml, ensure dependencies (and their versions) are up-to-date and correctly defined, for example:

[...]
<dependencies>
    <dependency>
        <groupId>org.jahia.modules</groupId>
        <artifactId>graphql-dxm-provider</artifactId>
        <version>3.0.0</version>
        <scope>provided</scope>
    </dependency>
    [...]
<dependencies>
[...]

The exact list of dependencies will depend upon your codebase.

By setting the parent version to Jahia 8.2.0.1, your module MUST be compiled with JDK11 or above and MUST be using jahia.plugin.version  6.9. It cannot be compiled with JDK8 nor use an older version of the Jahia Plugin.

Step 4: Update your modules codebases

Additional adjustments might be needed in your codebase (mostly in its pom.xml) to adapt to changes in Jahia 8.2.0

OpenJDK 11+

Jahia 8.2.0 is not compatible with JDK8, if some of your modules rely on features only present in JDK8, these would need to be updated.

The following APIs were deprecated in previous JDK releases and removed from JDK 11:

javax.security.auth.Policy 
java.lang.Runtime.runFinalizersOnExit(boolean)
java.lang.SecurityManager.checkAwtEventQueueAccess() 
java.lang.SecurityManager.checkMemberAccess(java.lang.Class,int)
java.lang.SecurityManager.checkSystemClipboardAccess()
java.lang.SecurityManager.checkTopLevelWindow(java.lang.Object)
java.lang.System.runFinalizersOnExit(boolean)
java.lang.Thread.destroy()
java.lang.Thread.stop(java.lang.Throwable)

Review your module codebase and check if you are using these APIs, and if you are, you will need to update your codebase to an alternative approach. You can review this JDK 11 migration guide and find native alternatives in the JDK 11 API documentation.

In general, and outside of the deprecated APIs, it is recommended to review the JDK 11 migration guide as it might contain relevant information specific to your codebase.

Once done, make sure to update your environment to support building your module with JDK 11, this is typically done by pointing your “JAVA_HOME” to your local install of JDK11.

Limit exposure of Shiro library

To enhance code flexibility and mitigate direct dependencies on third-party libraries, we have now limited direct exposure of Shiro classes and provide Jahia utilities instead for some security functionalities. If your module was using shiro classes ”org.apache.shiro” to check on an authenticated user for example Jahia 8.2 now provides utility classes to use instead of accessing Shiro yourself.

For example code like this:

Subject subject = WebUtils.getAuthenticatedSubject(httpServletRequest);
if (subject != null && subject.hasRole(REQUIRED_ROLE)) {
    // user has the required role: allow access
    return;
}

Should be simplified like this:

WebUtils.authenticatedSubjectHasRole(httpServletRequest, REQUIRED_ROLE)

Rome removal

Jahia before 8.2 was embedding rome-1.0.jar and exposing the corresponding classes “com.sun.syndication”, if your module needs those classes you now need to embed them by adding this to your pom.xml dependencies:

<dependency>
    <groupId>rome</groupId>
    <artifactId>rome</artifactId>
    <version>1.0</version>
</dependency>

JDOM2 migration

In Jahia 8.2.0, JDOM was replaced by JDOM2, if “org.jdom” is present in your codebase, it should be replaced by “org.jdom2” and your dependencies should be updated. There should be no other changes needed.

We do not recommend keeping jdom v1 in your codebase, even for modules compatible with Jahia 8.1x

DOM4J migration

If your module is using DOM4J there should be nothing else to be done than recompiling with 8.2 as DOM4J 2.1.4 is a drop-in replacement for DOM4J 1.6.1

Apache Commons OGNL removal

Jahia before 8.2 was embedding ognl-3.2.21.jar

If your module needs those classes you now need to embed them by adding this to your pom.xml dependencies:

<dependency>
    <groupId>ognl</groupId>
    <artifactId>ognl</artifactId>
    <version>3.2.21</version>
</dependency>

But be aware that OGNL can represent a security risk and should be removed from your system (see https://www.contrastsecurity.com/glossary/ognl-injection-ognl).

Apache Portlet removal

Portlet functionality has been removed from 8.2 after having been deprecated since 8.0. 

The only option moving forward is to convert your existing portlets into Jahia 8.2 modules by rewriting them.

OSGIv7 and Karaf 4.3.10 upgrade

The upgrade of Jahia 8.2 to Karaf 4.3.10 and OSGI V7 changed some exported packages. Specifically, the package “org.osgi.service.component.annotations” has been removed as an exported package. 

Users can use bnd tools (bnd print -i <module.jar>) to check if this package is currently required by the module.

Jgroups 3.6.20

JGroups is used for cluster communication, unless you have created your own channels this upgrade should not impact your project. 

If you find that your project uses org.jgroups classes then you will need to update your dependency to 3.6.20.Final and recompile/redeploy your module. 

If you have created your own protocols for JGroups then you might need to adapt your code as there were changes in classes such as org.jgroups.protocols.PingData

Hazelcast 3.12.13

Hazelcast 3.12.13 is a drop-in replacement, this should concern you only if you are using Hazelcast in your code, look for classes from com.hazelcast and if present, you should update your dependency to 3.12.13, and recompile/redeploy your project.

Apache Tika 2.9.1

Apache Tika 2.9.1 should be a drop-in replacement. If you are using classes from org.apache.tika then you should update your pom.xml and recompile/redeploy your project.

Spring 5 Karaf feature

Spring 5 will not be packaged into the Jahia OSGI system by default, it used to be provided as a Karaf feature and OSGI bundles using the official Karaf spring feature.

In case your implementation relies on this Spring version, you will have to install it using the Jahia provisioning API (on each node of your Jahia cluster) :

- installFeature: 'spring'
Karaf features are not officially supported by Jahia, so use it at your own risks.
There is no need to add the feature repo for Spring, it's already configured according to the current running Karaf version. (meaning that the Spring version will be the official Karaf spring version available for the currently running Karaf (for Jahia 8.2.0.1 it will be Spring 5.3.29 provided by feature repo: mvn:org.apache.karaf.features/spring/4.3.10/xml/features))

Google Guava 33.0

Until Jahia 8.2.0, the Google Guava library was exposed twice in OSGI, this was addressed in Jahia 8.2.0 which is only exposing the library once. 

In previous versions of Jahia, the library was automatically exposed as a transitive dependency. Via the parent object, your project was automatically inheriting all jahia-modules dependencies (such as Google Guava) allowing you to use the library in your code without needing to declare a direct dependency on Guava. Since this pattern was problematic, the decision was made to stop exposing the library automatically and require consumers of the library to declare it explicitly.

[...]
<dependencies>
    <dependency>
       <groupId>com.google.guava</groupId>
       <artifactId>guava</artifactId>
       <scope>provided</scope>
    </dependency>
    [...]
<dependencies>
[...]

For the time being, Guava is the only library impacted, but Jahia is progressively taking the direction of requiring explicit imports, which aligns with best practices.

jQuery 3.7.1

In previous versions of Jahia, multiple versions of jQuery were available in parallel, including a fairly old version (1.10.2). With Jahia 8.2.0, these old versions were removed and only jQuery 3.7.1 was kept.

jQuery 1.10.2 was previously accessible at /css/jquery.min.js and was originally aimed at being used only internally by Jahia backend UIs. If you used this library in any of your projects, you should update your code to use either jQuery 3.7.1 provided by the jquery module or another jQuery embedded into your module. 

Removal of user template from template-system

With Jahia 8.2, the template system module does not provide any template for user nodes. If this template was used by one of your modules, you should update it to use a dedicated template instead.

As an example you can check the the jahia/userDashboard module user template here.

 

Step 5: Address potential OSGI wiring issues

When deploying your modules on Jahia 8.2 you might face OSGI wiring issues that would prevent your module from being deployed properly.

Such errors are typically caused by updates either to libraries directly imported by your module or by an update of a library provided with Jahia 8.2, and would look like this (with different package names):

org.osgi.framework.BundleException: Unable to resolve mymodule [167](R 167.10): missing requirement [mymodule [167](R 167.10)] 
osgi.wiring.package; (&(osgi.wiring.package=org.osgi.service.jdbc)(version>=1.0.0)(!(version>=2.0.0))) 
Unresolved requirements: [[mymodule [167](R 167.10)] osgi.wiring.package; (&(osgi.wiring.package=org.osgi.service.jdbc)(version>=1.0.0)(!(version>=2.0.0)))]

Assuming the previous step highlights an issue with the package "org.osgi.service.jdbc" (as an example), use Jahia Maven OSGI tool to identify where this package is used:

mvn jahia:find-package-uses -DpackageNames=org.osgi.service.jdbc

[INFO] +- com.microsoft.sqlserver:mssql-jdbc:jar:9.4.1.jre11 :
[INFO] 	+--> Found class com.microsoft.sqlserver.jdbc.osgi.Activator that uses package org.osgi.service.jdbc
[INFO] 	+--> Found class com.microsoft.sqlserver.jdbc.osgi.SQLServerDataSourceFactory that uses package org.osgi.service.jdbc

The command above informs us that this package is imported due to a dependency to the MSSQL jdbc driver that was included in our module.

From that point we could identify that:

  • Option 1: the package is linked to a side function that does not need to be present, it can be tagged as optional
  • Option 2: the package is mandatory for the dependency to work properly

In our example above, the package is not needed directly by our module and can be marked as optional.

Option 1: Mark the package optional.

This modification can be done in the OSGI import-package directive of your pom.xml

<property>
    <import-package>
        org.osgi.service.jdbc;resolution:=optional,
    </import-package>
</property>

Option 2: Explicitly provide the package

If the package is required for your module to work, you would need to add it as a dependency in your pom.xml as detailed in step 1 of this document.

Begin by identifying which maven artifact solves (or contains) the required package, then update your pom.xml accordingly.

With OSGI introspection for wiring issues you’ll probably face many missing packages related to bouncycastle.  This is a common wiring problem associated with Apache POI which provides tooling around cipher and signing. In such situations, you could decide either to make the bouncycastle packages optional or to integrate it in your module as an internal dependency by adding the corresponding maven artifact: 

<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcpkix-jdk18on</artifactId>
    <version>1.76</version>
</dependency>

 

Other changes

New permission is required for provisioning API

The provisioning API is not attached to the “systemTools” permission anymore but is using a dedicated permission called “provisioningAccess”. 

The goal of this new permission is to allow for fine-grain access to the API and its operations. We took the decision (see Principle of Least Privilege) not to implement a migration script to this new permission and it will need to be set-up manually when migrating from Jahia 8.1x. This only applies if you were relying on the “systemTools” permission to access the provisioning API.

The provisioning API remains open to the root user and system-administrator role.

Deprecation of JCRContentUtils.size

This method has been deprecated because the method will consume the iterator passed as a parameter to count its elements. It’s problematic because after a call to this method, the iterator cannot be reused to iterate through the elements.

Furthermore, the more items there are, the longer it will take to get the iterator size. In case of a large volume of data, calling this method could affect the performance of the platform.

When an implementation necessitates knowing the size of data, it is advised to perform a query on the JCR to determine the count of items beneath a node, rather than relying on JCRContentUtils.size.

JDK 17 support

If you are not using Docker nor Jahia Cloud, your Jahia environment can be made compatible with JDK 17 by adding the following to JDK_JAVA_OPTIONS (see example here).

--add-opens=java.base/java.net=ALL-UNNAMED

This command, java.base/java.net=ALL-UNNAMED means "export the java.net package of the java.base module to all unnamed modules". This allows the library in your unnamed module (the classpath) to access that internal API.

GraalVM support

Jahia 8.2 introduces support for GraalVM, which is the required JDK for use with javascript modules.

To use GraalvVM with javascript modules, the javascript engine must be installed, this can be done using the following command:

gu install js
Jahia Cloud or Jahia Docker images do use GraalVM (with the javascript engine installed), so if you are on one of these two deployment scenario, you do not have anything to do.

If the javascript engine is not installed the following errors will be present in your Jahia logs:

2024-03-28 07:40:18,907: ERROR [FelixDispatchQueue] org.jahia.modules.npm.modules.engine.NpmModuleListener: Cannot handle event org.osgi.framework.BundleEvent[source=solid-template [189]]
org.jahia.modules.npm.modules.engine.jsengine.GraalVMException: Unable to borrow context from pool: A language with id 'js' is not installed. Installed languages are: [].
    at org.jahia.modules.npm.modules.engine.jsengine.GraalVMEngine.doWithContext(GraalVMEngine.java:133) ~[?:?]

CSRF TokenPerPage

TokenPerPage is now set to true by default, more details can be found on this academy page.

Limited support for webp

With Jahia 8.2.0.1, there is limited support for webp images in jContent.

This will be improved in future versions of jContent.

Removal of Jahia Captcha

Google Kaptcha 2.3 has been removed in Jahia 8.2.0 we recommend to look at newer alternatives, such as Google reCaptcha, which is more secure and provides a better experience.

Find out how to use reCaptcha with Jahia.

New server response codes when accessing protected resources

In earlier versions, Jahia was handling pages and files differently, when such resources were accessed by a user who did not have the read permission on them:

Behavior 1 - secure, no 401/403 - current files behavior

  • resource exists : served, 200
  • resource does not exist or is not accessible : 404

Behavior 2 - disclosing protected resources - current page behavior

  • resource exists : served, 200
  • resource exist, guest user, require authentication : 401
  • resource exist, logged in, user not allowed : 403
  • resource does not exist : 404

In Jahia 8.2, we've ensured the same behavior was present for pages and files. Customers will be able to choose which one of the two behaviors to use. By default, Jahia will use the first behavior, only serving 200 and 404 pages in live, as it is more secure and does not disclose the existence of protected resources.

If it’s not already the case, we encourage our customers to display a login form on the 404 error page, displayed when the user is unauthenticated. This will allow a user to sign in and access the resource, if allowed, right after signing in.