Upgrade Guide to Jahia 8.2.0

July 30, 2024

Jahia 8.2 is a feature release with a strong focus on addressing technical debt and upgrading libraries, it comes with noticeable improvements and changes related to:

  1. Our supported stack
  2. Library updates and removal
  3. Module updates and removal
  4. Platform updates
  5. Module development

Despite the array of new features and changes, the Jahia team has invested significant effort to ensure that upgrading from 8.1 to 8.2 is as straightforward as it can be. The main new features being optional, it is possible to adopt them progressively over a few months, post-upgrade, at your own pace.

For each of these points, the goal is to give you a clear view of what impacts it may have on your environment and guide you on what you may have to do.

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. 

Jahia supported stack

Jahia revised its supported stack and introduced support to newer versions of its dependencies.

In hindsight, the following changes were made:

  • Support for JDK8 was dropped, and support for JDK 17 was added
  • Support for database versions was updated (please refer to the support stack page)
Action: Review the Supported Stack page and make sure your environment complies with the supported stack for Jahia 8.2

Libraries updates and removal

Updates to libraries exposed by Jahia

A sizeable number of libraries have been updated between Jahia 8.1.7 and Jahia 8.2.0, but depending on your own codebase, you are not necessarily impacted by these changes. If you are, require modifications can range from simple recompilation to a full refactor of some methods.

Reminder: At Jahia we recommend explicitly declaring your dependencies (see the dedicated page on the academy detailing best practices) and not depending on libraries exposed by Jahia core. If you are already doing so, you will not be impacted by any of these library updates and can move to the next section.

Action: Identify dependencies to libraries exposed by Jahia and used in your codebase.

You can list all import packages in your codebase by using the bndtools:

  1. Retrieve the list of packages imported by your codebase using the following command:  bnd print -i <module.jar>
  2. From that list:
    • Remove imports related to java itself (starting with javax)
    • Remove imports related to modules developed by Jahia (starting with org.jahia)
    • Remove imports related to your own modules
  3. Take the resulting list and compare it to the upgraded libraries listed in the table below.
  4. If you see one or more impacted libraries:
    • Most of these libraries adhere to SemVer, meaning a change in the first digit (major) introduces breaking changes and should be reviewed with the utmost care. In most situations, updates to the other digits are unlikely to be a source of concern.
    • For major digit changes, review the corresponding libraries' changelogs (all changelogs between the version you are using and the version you are updating to) and assess how your codebase could be impacted by these breaking changes (they might not).
    • For minor or patch digit changes, it remains a best practice to review all changelogs.
  5. If a version range is returned by the bndtool, make sure this version is compliant with the version the library was updated to, if not you will need to update the version range in your pom.xml
    • Example:
      • If you see the following output: com.fasterxml.jackson.core             {version=[2.13,3)}
      • This indicates that your codebase is expecting jackson between version "2.13.0" (included) and up to "3.0.0" (excluded).
      • For Jahia 8.2 you are fine since Jackson was updated to version 2.15.2 (which is in the range).

Upgraded libraries

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.4
Apache Commons Collections 3.2.2 3.2.2-jahia
Apache Commons Compress 1.21.0 1.25.0
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 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
EHCache 2.8.5 2.10.9.2
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
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 Mail 1.6.1 1.6.2
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
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

Removed 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 document provides pointers to updating your codebase to use alternative solutions.

Library Version in Jahia 8.1.7.1 Version in Jahia 8.2.0.4
Apache Commons Ognl 3.2.21 Removed
Apache Portals Portlet API 1.0 Removed
Apache Portals Pluto Libraries 2.0.2 Removed
Eclipse JDT Core Compiler 4.6.1 Removed
Google Kaptcha 2.3 Removed
Hibernate ORM 5.5.3.Final 5.5.3.Final
Not exposed anymore
Javax XML Bind 2.3.1 Removed
Javax Portlet API 2.0 Removed
Rome 1.0 Removed
Yahoo YUI Compressor 2.4.9-20161014 Removed

Hibernate

Action: Identify if you are using Hibernate, if you do, follow the instructions in this section.

Hibernate 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

Action: Identify if you are using Spring events, if you do, follow the instructions in this section.

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

Action: Identify if you are using Spring, if you do, follow the instructions in this section.

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

Modules updates and removal

Modules with dual compatibility

Action: If you are currently using some of the modules listed here, you should update them before beginning the migration to Jahia 8.2

Although a newer version of these modules was released to introduce compatibility with Jahia 8.2,  we managed to maintain compatibility with Jahia 8.1. There is no technical requirement to update these modules before upgrading to Jahia 8.2 but an upgrade is required for them to work with Jahia 8.2. Doing so in advance is going to simplify your upgrade process as it will be one item less to perform on the day of the migration.

These modules are not packaged with the Jahia, you need to update them individually.

Module Version
Augmented Search 3.6.0
Database Connector 1.6.0
Distributed Sessions 3.5.0
Elasticsearch Connector 3.3.1
Forms Core 3.12.0
JCR Auth Provider 3.4.1

Modules with breaking changes

Action: Review the breaking changes documented in this table, and evaluate their impact on your environment.

The following modules received a major update and could contain changes considered breaking for your codebase.

Module Version in Jahia 8.1.7.1 Version in Jahia 8.2.0.4 Breaking changes
App Shell 2.9.0 3.1.0 Modified the redirection mechanism for custom login or custom error pages. More details are provided on this page.
GraphQL Provider 2.19.1 3.0.0 Updated graphql-java from 13.0 to 21.3, if you're using graphql annotations in your codebase, review the documented breaking changes
jContent

2.13.0

3.0.1 See the "Content Editor module merged into jContent" section of this document for the list of changes. Breaking changes are also listed on the module's page on Jahia Store.

Other modules updates

The following modules received a major version update but are only listed here for information as they do not contain changes considered breaking for your codebase.

These first-digit updates were necessary to make room for potential evolutions in versions of the module compatible with Jahia 8.1.

These modules are present by default with Jahia, they will be updated automatically during the migration process.

Module Version in Jahia 8.1.7.1 Version in Jahia 8.2.0.4 Breaking changes
CSRF Guard 3.4.0 4.0.0 This version is compatible only with Jahia 8.2. No breaking changes are present.
Remote Publish 9.7.0 10.0.0 This version is compatible only with Jahia 8.2. No breaking changes are present.
Site Settings SEO 4.4.0 5.0.1 This version is compatible only with Jahia 8.2. No breaking changes are present.
Tools 4.4.0 5.0.1 Removed the deprecated Portlet feature and dependencies, no expected impact on your codebase.

Modules to update individually

Action: If you are currently using some of the modules listed here, take note that these will need to be updated individually at the end of the migration. A reminder is also present in the upgrade instructions.

Similar to the modules in the previous section, new modules were released and with a first-digit bump. Since these modules are not packaged with Jahia, they will need to be updated individually at the end of the migration process.

Module Version compatible with Jahia 8.1 Version compatible with Jahia 8.2 Breaking changes
CMIS Provider 3.3.0 4.0.0 This version is compatible only with Jahia 8.2. No breaking changes are present.
Copy to other languages 2.1.0 3.0.1 This version is compatible only with Jahia 8.2. No breaking changes are present.
Jahia Globallink Translation 3.3.0 4.0.0 This version is compatible only with Jahia 8.2. No breaking changes are present.
Siteimprove Connector 2.1.2 3.0.2 This version is compatible only with Jahia 8.2. No breaking changes are present.

Modules removed from Jahia distribution

The following modules previously present are not available by default when starting a Jahia 8.2.0. They can be installed independently from the store if required.

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.

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.

jExperience compatibility

Jahia 8.2.0 is not compatible with jExperience 2 (and jCustomer 1), before upgrading to Jahia 8.2.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.

Platform updates

Elements listed in this section contain changes at a platform level that will unlikely require a change in your codebase but instead to the Jahia environment itself (deployment of modules, configuration to the Jahia platform, ...).

Content type provided by Jahia

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, 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] 

Catalina and JDK options

Action: Ignore this section if using Jahia Cloud or Jahia Docker images.

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"

New permission 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, 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.

Modules development

Elements listed in this section contain changes potentially necessary in your own codebase (mostly in your module's pom.xml) to adapt to changes in Jahia 8.2.0.

OpenJDK 11+

Action: Ignore this section if you were already building and running your modules with JDK 11

Jahia 8.2.0 is not compatible with JDK8, if some of your modules rely on features only present in JDK 8, 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.

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.

Changes to libraries

Action: In the "Libraries updates and removal" we provided instructions on how to use bndtool to detect the presence of libraries in your codebase, look at the provided list, and if you don't find any of the following libraries present, you can skip this section:
  • Apache Commons OGNL
  • Apache Karaf
  • Apache Portlet
  • Apache Shiro
  • Apache Tika
  • Dom4j
  • Google Guava
  • Hazelcast
  • jdom & jdom2
  • JGroups
  • jQuery
  • OSGI
  • Rome
  • Spring 5

Otherwise, you will likely need to update your codebase, instructions are provided below for each library.

Apache Commons OGNL

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 Karaf 4.3.10 and OSGIv7

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.

Apache Portlet

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.

Apache Shiro

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)

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.

DOM4J

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

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.

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.

JDOM2

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

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

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. 

Rome

Jahia before 8.2 was embedding rome-1.0.jar (Rome has been removed in Jahia 8.2) 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>

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.4 it will be Spring 5.3.29 provided by feature repo: mvn:org.apache.karaf.features/spring/4.3.10/xml/features))

Best practices for modules development

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).

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.

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>

Upgrading to Jahia 8.2

Recommendations

jExperience compatibility (reminder)

Jahia 8.2 is NOT compatible with jExperience 2 (and jCustomer 1), before upgrading to Jahia 8.2, 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 and Jahia 81x, make sure to review jExperience 3 migration guide.

Obtaining a Jahia 8.2.0 license

If you were using a previous version of Jahia 8 with a free license key, you will need to get a new one to run Jahia 8.2.0. You can use this form, to instantaneously receive a new and free license key for a standalone environment.

It is not necessary to request a new license key if you already have a Jahia 8 license key for production or cluster environements.

HTML Filtering

In versions prior to Jahia 8.2.0, it was possible to remove specific tags from rich text fields (e.g. to prevent authors from entering <script> tags in their rich texts), by enabling the HTML filtering feature. The approach was to allow every tag that was not explicitly denied.
With Jahia 8.2.0, we are moving to a safer approach, consisting in denying all the html tags, and attributes, which are not explicitly allowed. You can find the list of html tags and attributes allowed by default in Jahia here (org.jahia.modules.htmlfiltering.config-default.yml). This default configuration can be updated, so it applies on all sites. It is also possible to provide custom configuration per site.
Also note that this new module is compatible with previous Jahia versions starting with 8.1.5.

Customers who did not activate the HTML filtering on their sites are not impacted by this change:

  • If HTML filtering was not activated in your site on 8.1.x, it won’t be activated also in 8.2.0 (nothing change)
  • However, we do recommend you to take actions and activate it, as it is a security feature (see the documentation)

Module start level

When preparing your upgrade and to avoid problems during startup, you'll need to check the start-level of your modules and make sure that all of them have the correct start-level. You'll find more details here: Monitoring start-level of your modules

API default authorization

During the upgrade you might notice an error telling you that org.jahia.bundles.api.authorization-default.yml couldn't be merged automatically. As often with XML and YML files the merge can get complicated, but in this case the most recent one can be used (org.jahia.bundles.api.authorization-default.yml.new), you just need to ensure you only have one occurence of this file in digital-factory-data/karaf/etc/ (use the one with the .new extension) so that it can be loaded.

Installation path

When Jahia is operating in cluster, it is recommended for the installation path to be the same across all nodes of the cluster. Except if part of an exclusion list, configuration files are automatically sync'ed across a cluster, if a configuration property contains a full path, and if that path is different across the cluster nodes, this can cause inconsistencies and stability issues. This does not apply to users of Jahia Cloud or Jahia Docker images as this behavior is baked in.

Performing the upgrade

Please follow the instructions on this page dedicated to the upgrade itself:

How to upgrade from 8.1.7.1 to 8.2.0.4