Server

Hotfixes Installation Notes

Updated: June 19, 2024

The purpose of this page is to describe the additional actions that need to be done when installing the hotfixes on Nuxeo Platform and that cannot be done automatically. The page provides an exhaustive list of manipulations for the installation of Nuxeo Platform LTS 2023 hotfixes, but you need only to apply those relevant for your own instance.

When you are installing/configuring a new Nuxeo instance, the very first thing to do is to install the hotfixes. Because it will provide fixes on the Nuxeo launcher, on the startup wizard and on the templates, installing them immediately will prevent from encountering known issues.

How to Keep Your Instance up-to-Date

Hotfixes always have dependencies on the previous hotfix. So if you need to install several hotfixes, you can download only the latest one: when you install it, it will trigger the installation of the previous hotfixes.

Installing Hotfixes from the Command Line

The Nuxeo Platform provides a command to automatically install all the available hotfixes. From the command line, run the following command:

  • For Linux and Mac OS users:

    $ ./nuxeoctl mp-hotfix --accept=true
    
  • For Windows users:

    > nuxeoctl.bat mp-hotfix --accept=true
    

The parameter --accept=true automatically replies yes to any prompt, which makes the hotfix installation smoother.

While installing hotfixes, you will see the following message, but you can ignore it and continue.

Use of the <copy /> command on JAR files is not recommended, prefer using <update /> command to ensure a safe rollback. (nuxeo-launcher-8.10-HF01-jar-with-dependencies.jar)

Installing Hotfixes from the Update Center

You can also download and install hotfixes from the Update Center in the Admin tab.The installation of hotfixes requires the server to be restarted to complete the installation: follow the manual installation and configuration steps required by the installed hotfixes before you restart your server.

While installing hotfixes, you will see the following message, but you can ignore it and continue.

Use of the <copy /> command on JAR files is not recommended, prefer using <update /> command to ensure a safe rollback. (nuxeo-launcher-9.10-HF01-jar-with-dependencies.jar)

Since LTS 2021, the addon "Nuxeo JSF UI" is handled outside the main Nuxeo repository on GitHub. As a consequence, the related fixes for JSF UI will not be embedded in a hotfix.
Therefore if the addon "Nuxeo JSF UI" is installed on your instance, you must upgrade this package after installing a hotfix by running the following command:

> nuxeoctl mp-upgrade

Note that this command will upgrade the versions of any package.

Instance Registration

Hotfixes released for LTS 2023 can only be used on valid, registered Nuxeo instances.

Why?
If you are using an unregistered LTS 2023 Nuxeo instance with hotfixes installed, you may encounter the following behavior:

  • A warning will be displayed in the logs during startup,
ERROR [RuntimeService] NUXEO INSTANCE NOT REGISTERED

***** This Nuxeo instance is not registered *****
It can only be used for development and will be stopped if used in production
  • Over a certain level of use the server will be stopped automatically. When this happens, a message is displayed in the logs to inform you as well.
ERROR [RuntimeService] NUXEO INSTANCE STOPPING

***** This Nuxeo instance is not registered *****
Stopping Nuxeo instance due to threshold exceeded (TOTAL_COMMITS > 100000) after failed registration checks

The current limits of use are:

  • 100,000 transaction commits
  • 10 concurrent sessions (a session correspond to an access to the core)

If the expiration date is close (less than 15 days), a warning will be displayed and indicate how many days are left before expiration. In the JSF UI, a message based on the Administrative message mechanism will be displayed: all users will be informed.

After expiration date, the following message will be displayed in the logs at startup:

ERROR [RuntimeService] NUXEO INSTANCE REGISTRATION EXPIRED

***** This Nuxeo instance registration is expired *****
It can only be used for development and will be stopped if used in production

The following message will be displayed in the logs when Nuxeo will be stopped automatically according to the same conditions as described earlier:

ERROR [RuntimeService] NUXEO INSTANCE STOPPING

***** This Nuxeo instance registration is expired *****
Stopping Nuxeo instance due to threshold exceeded (TOTAL_COMMITS > 100000) after registration expiration

How Can I Avoid This?

Make sure to register your Nuxeo instance: this can be done both for online and offline instances.

Could it Break My CI Chain? Do I Need to Register My Test Instances?

The level of use needed to stop an unregistered instance with hotfixes has been tuned to prevent any problems with CI chain tests. It would be possible to run the full test suite of Nuxeo server (both unit tests AND integration tests) several times before anything would happen.

Nevertheless, it is recommended to register your test instances, especially if you wish to test features that require heavy usage (e.g. load testing or mass import).

How Often Do I Need to Register My Instance?

Registration tokens are valid until your current contract's expiration date. When renewing your Nuxeo Online Services subscription, you should register your instances again.

I Have More Questions, Who Can I Ask For Help?

If you have any questions, feel free to contact our support team via a dedicated support ticket.

Hotfix 12

Use Keycloak Auth After Automation Basic Auth in Specific Auth Chains

Now when doing automation or rest calls, Automation basic auth precedes Keycloak auth. This brings change to the response status codes to expect.

These have been documented in the Nuxeo Keycloak documentation alongside with a sample xml contrib to reverse back the auth plugins order to the older state.

 More on JIRA ticket NXP-32514

Hotfix 11

Upgrade Commons-Cli From 1.6.0 to 1.7.0

commons-cli:commons:cli was upgraded from 1.6.0 to 1.7.0.

 More on JIRA ticket NXP-32498

Hotfix 10

Handle Openpdf Upgrade Dependabot Pull Request

The com.github.librepdf:openpdf dependency has been upgraded from 1.3.40 to 1.4.1. Thus, the AcroFields#getSignatureNames() method isn't available anymore, it is replaced by AcroFields#getSignedFieldNames().

 More on JIRA ticket NXP-32386

Provide Option to Enable Nashorn Optimistic Typing

A new framework property allows to toggle this behavior by adding the following to your nuxeo.conf:

nuxeo.automation.scripting.optimistic.types.enabled=true

 More on JIRA ticket NXP-32342

Add Support of Keycloak 24.0.x

The following dependency (Keycloak BOM) has been removed:

<dependency>
  <groupId>org.keycloak</groupId>
  <artifactId>keycloak-tomcat-adapter-dist</artifactId>
</dependency>

in favor of:

<dependency>
  <groupId>org.keycloak</groupId>
  <artifactId>keycloak-tomcat-adapter</artifactId>
</dependency>
<dependency>
  <groupId>org.keycloak</groupId>
  <artifactId>keycloak-common</artifactId>
</dependency>
<dependency>
  <groupId>org.keycloak</groupId>
  <artifactId>keycloak-crypto-default</artifactId>
</dependency>
<dependency>
  <groupId>org.keycloak</groupId>
  <artifactId>keycloak-policy-enforcer</artifactId>
</dependency>

The version of these artifacts has been upgraded from 19.0.3 to 24.0.2.

 More on JIRA ticket NXP-32352

Hotfix 9

Update H2database Dep to 2.2.220

The following dependency was upgraded from 2.1.214 to 2.2.224:

<dependency>
  <groupId>com.h2database</groupId>
  <artifactId>h2</artifactId>
</dependency>

If on start you encounter the following exception, you have to delete the ${nuxeo.data.dir}/h2 directory. Yet, you will LOSE DATA if you use the default H2 backend. This should mainly impact development environments, as H2 must never be used in production.

2024-03-06T12:53:46,788 WARN  [JdbcEnvironmentInitiator] HHH000342: Could not obtain connection to query metadata
java.sql.SQLException: Cannot create PoolableConnectionFactory (Unsupported database file version or invalid file header in file "/var/lib/nuxeo/nuxeo-server-tomcat-2023.7-SNAPSHOT/nxserver/data/h2/nuxeo.mv.db"
Unsupported database file version or invalid file header in file "/var/lib/nuxeo-server-tomcat-2023.7-SNAPSHOT/nxserver/data/h2/nuxeo.mv.db" [90048-224])
    at org.apache.commons.dbcp2.managed.BasicManagedDataSource.createPoolableConnectionFactory(BasicManagedDataSource.java:155) ~[commons-dbcp2-2.11.0.jar:2.11.0]
    at org.apache.commons.dbcp2.BasicDataSource.createDataSource(BasicDataSource.java:535) ~[commons-dbcp2-2.11.0.jar:2.11.0]
    at org.apache.commons.dbcp2.BasicDataSource.getConnection(BasicDataSource.java:711) ~[commons-dbcp2-2.11.0.jar:2.11.0]
    ...
Caused by: org.h2.jdbc.JdbcSQLNonTransientConnectionException: Unsupported database file version or invalid file header in file "/var/lib/nuxeo/nuxeo-server-tomcat-2023.7-SNAPSHOT/nxserver/data/h2/nuxeo.mv.db"
Unsupported database file version or invalid file header in file "/var/lib/nuxeo/nuxeo-server-tomcat-2023.7-SNAPSHOT/nxserver/data/h2/nuxeo.mv.db" [90048-224]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:690) ~[h2-2.2.224.jar:2.2.224]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:489) ~[h2-2.2.224.jar:2.2.224]
    at org.h2.message.DbException.get(DbException.java:212) ~[h2-2.2.224.jar:2.2.224]
    at org.h2.mvstore.db.Store.convertMVStoreException(Store.java:158) ~[h2-2.2.224.jar:2.2.224]
    at org.h2.mvstore.db.Store.<init>(Store.java:142) ~[h2-2.2.224.jar:2.2.224]
    at org.h2.engine.Database.<init>(Database.java:326) ~[h2-2.2.224.jar:2.2.224]
    at org.h2.engine.Engine.openSession(Engine.java:92) ~[h2-2.2.224.jar:2.2.224]
    at org.h2.engine.Engine.openSession(Engine.java:222) ~[h2-2.2.224.jar:2.2.224]
    at org.h2.engine.Engine.createSession(Engine.java:201) ~[h2-2.2.224.jar:2.2.224]
    at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:343) ~[h2-2.2.224.jar:2.2.224]
    at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:125) ~[h2-2.2.224.jar:2.2.224]
    at org.h2.Driver.connect(Driver.java:59) ~[h2-2.2.224.jar:2.2.224]
    at org.apache.commons.dbcp2.DriverConnectionFactory.createConnection(DriverConnectionFactory.java:52) ~[commons-dbcp2-2.11.0.jar:2.11.0]
    at org.apache.commons.dbcp2.managed.LocalXAConnectionFactory.createConnection(LocalXAConnectionFactory.java:359) ~[commons-dbcp2-2.11.0.jar:2.11.0]
    at org.apache.commons.dbcp2.managed.PoolableManagedConnectionFactory.makeObject(PoolableManagedConnectionFactory.java:77) ~[commons-dbcp2-2.11.0.jar:2.11.0]
    at org.apache.commons.dbcp2.BasicDataSource.validateConnectionFactory(BasicDataSource.java:113) ~[commons-dbcp2-2.11.0.jar:2.11.0]
    at org.apache.commons.dbcp2.managed.BasicManagedDataSource.createPoolableConnectionFactory(BasicManagedDataSource.java:151) ~[commons-dbcp2-2.11.0.jar:2.11.0]
    ... 76 more
Caused by: org.h2.mvstore.MVStoreException: The write format 2 is smaller than the supported format 3 [2.2.224/5]
    at org.h2.mvstore.DataUtils.newMVStoreException(DataUtils.java:996) ~[h2-2.2.224.jar:2.2.224]
    at org.h2.mvstore.FileStore.getUnsupportedWriteFormatException(FileStore.java:943) ~[h2-2.2.224.jar:2.2.224]
    at org.h2.mvstore.FileStore.processCommonHeaderAttributes(FileStore.java:547) ~[h2-2.2.224.jar:2.2.224]
    at org.h2.mvstore.RandomAccessStore.readStoreHeader(RandomAccessStore.java:227) ~[h2-2.2.224.jar:2.2.224]
    at org.h2.mvstore.FileStore.start(FileStore.java:916) ~[h2-2.2.224.jar:2.2.224]
    at org.h2.mvstore.MVStore.<init>(MVStore.java:289) ~[h2-2.2.224.jar:2.2.224]
    at org.h2.mvstore.MVStore$Builder.open(MVStore.java:2035) ~[h2-2.2.224.jar:2.2.224]
    at org.h2.mvstore.db.Store.<init>(Store.java:133) ~[h2-2.2.224.jar:2.2.224]
    at org.h2.engine.Database.<init>(Database.java:326) ~[h2-2.2.224.jar:2.2.224]
    at org.h2.engine.Engine.openSession(Engine.java:92) ~[h2-2.2.224.jar:2.2.224]
    at org.h2.engine.Engine.openSession(Engine.java:222) ~[h2-2.2.224.jar:2.2.224]
    at org.h2.engine.Engine.createSession(Engine.java:201) ~[h2-2.2.224.jar:2.2.224]
    at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:343) ~[h2-2.2.224.jar:2.2.224]
    at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:125) ~[h2-2.2.224.jar:2.2.224]
    at org.h2.Driver.connect(Driver.java:59) ~[h2-2.2.224.jar:2.2.224]
    at org.apache.commons.dbcp2.DriverConnectionFactory.createConnection(DriverConnectionFactory.java:52) ~[commons-dbcp2-2.11.0.jar:2.11.0]
    at org.apache.commons.dbcp2.managed.LocalXAConnectionFactory.createConnection(LocalXAConnectionFactory.java:359) ~[commons-dbcp2-2.11.0.jar:2.11.0]
    at org.apache.commons.dbcp2.managed.PoolableManagedConnectionFactory.makeObject(PoolableManagedConnectionFactory.java:77) ~[commons-dbcp2-2.11.0.jar:2.11.0]
    at org.apache.commons.dbcp2.BasicDataSource.validateConnectionFactory(BasicDataSource.java:113) ~[commons-dbcp2-2.11.0.jar:2.11.0]
    at org.apache.commons.dbcp2.managed.BasicManagedDataSource.createPoolableConnectionFactory(BasicManagedDataSource.java:151) ~[commons-dbcp2-2.11.0.jar:2.11.0]
    ... 76 more

 More on JIRA ticket NXP-32341

Hotfix 8

Throw an Error if a String Is Used to Query a Long/Integer Field

Added the nuxeo.primitive.type.strict.validation Framework property.

By default it is set to false, keeping the previous behavior: at low level, when trying to decode a string input as a number, fall back on 0 if the string cannot be decoded as a number, e.g. foo.

If set to true, in such case, a NumberFormatException is thrown.

Consequently, when executing a REST API search request on a PageProvider and passing foo as a query parameter for a predicate on an integer field, the server will respond with a 400 Bad Request status code, e.g.:

curl -u ******:******r -X GET http://localhost:8080/nuxeo/api/v1/search/pp/test_primitive_type_predicates/execute?integerField=foo | jq
{
  entity-type: exception,
  status: 400,
  message: java.lang.NumberFormatException: For input string: "foo"
}

 More on JIRA ticket NXP-32214

Hotfix 7

Add Support for ZIP Generated With 7-Zip and Including Files Whose Name Contains Special Characters

A fallback charset can be configured. This is being documented in nxdoc/preview. But here is the TL;DR:

<?xml version=1.0?>
<component name=org.nuxeo.ecm.zip.file.reader.fallback.config>
  <extension target=org.nuxeo.runtime.ConfigurationService point=configuration>
    <property name=org.nuxeo.ecm.zip.file.reader.charset.fallback>cp850</property>
  </extension>
</component>

 More on JIRA ticket NXP-32042

Hotfix 5

Upgrade or Remove Htmlunit From Nuxeo-Runtime-Test to Avoid Vulnerability

Removed the following Maven dependencies from nuxeo-runtime-test:

<dependency>
  <groupId>org.seleniumhq.selenium</groupId>
  <artifactId>selenium-api</artifactId>
</dependency>
<dependency>
  <groupId>org.seleniumhq.selenium</groupId>
  <artifactId>selenium-support</artifactId>
</dependency>
<dependency>
  <groupId>org.seleniumhq.selenium</groupId>
  <artifactId>selenium-firefox-driver</artifactId>
</dependency>
<dependency>
  <groupId>org.seleniumhq.selenium</groupId>
  <artifactId>selenium-ie-driver</artifactId>
</dependency>
<dependency>
  <groupId>org.seleniumhq.selenium</groupId>
  <artifactId>selenium-chrome-driver</artifactId>
</dependency>
<dependency>
  <groupId>org.seleniumhq.selenium</groupId>
  <artifactId>htmlunit-driver</artifactId>
</dependency>

Added the following Maven dependencies to nuxeo-features-test:

<dependency>
  <groupId>org.seleniumhq.selenium</groupId>
  <artifactId>selenium-firefox-driver</artifactId>
</dependency>
<dependency>
  <groupId>org.seleniumhq.selenium</groupId>
  <artifactId>selenium-ie-driver</artifactId>
</dependency>
<dependency>
  <groupId>org.seleniumhq.selenium</groupId>
  <artifactId>selenium-chrome-driver</artifactId>
</dependency>
<dependency>
  <groupId>org.seleniumhq.selenium</groupId>
  <artifactId>htmlunit-driver</artifactId>
</dependency>
<dependency>
  <groupId>org.assertj</groupId>
  <artifactId>assertj-core</artifactId>
  <scope>compile</scope>
</dependency>

Moved the following classes from nuxeo-runtime-test to nuxeo-features-test:

Attachment.java
Browser.java
BrowserFamily.java
ConcordionFixture.java
Configuration.java
DriverFactory.java
HomePage.java
SkipBrowser.java
TakesAttachment.java
WebDriverFeature.java
WebPage.java
ExpectedCondition.java
TimeoutException.java
Wait.java
WebDriverWait.java
MyHomePage.java
SearchResultPage.java
WebTest.java

The related package names haven't changed:

org.nuxeo.runtime.test.runner.web
org.openqa.selenium.support.ui

If you are explicitly depending on one of these classes, you need to replace the Maven dependency:

<dependency>
  <groupId>org.nuxeo.runtime</groupId>
  <artifactId>nuxeo-runtime-test</artifactId>
  <scope>test</scope>
</dependency>

by:

<dependency>
  <groupId>org.nuxeo.ecm.platform</groupId>
  <artifactId>nuxeo-features-test</artifactId>
  <scope>test</scope>
</dependency>

 More on JIRA ticket NXP-32144

Fix Results Selection Actions Made From Multi-Repository Search Results

Added:

  • nuxeo.bulk.download.multi.repositories Framework property
  • AbsoluteDocumentRef
  • TypeAdapterHelper#createDocumentModel(AbsoluteDocumentRef docRef)
  • DocumentInputResolver#BULK_DOWNLOAD_MULTI_REPOSITORIES
  • TestDocumentInputResolvers
  • MultiRepositoryDummyOperation

 More on JIRA ticket NXP-31487

Hotfix 4

Factorize Email Sending Code

Compatibility with Custom jndi Sessions

Compatibility has been ensured for users that contributed a custom jndi session name via a general settings contribution. A JndiSMTPMailSender is contributed on the fly at server start and a warning will be given so users can be aware they need to contribute their own MailSender.

A JndiSMTPMailSender can also be contributed by the users like below but bear in mind this is only a compatibility implementation and we encourage you to leverage another implementation of MailSender instead:

<?xml version=1.0?>
<component name=org.nuxeo.mail.my.sender.contrib>
  <extension target=org.nuxeo.mail.MailServiceComponent point=senders>

    <sender name=mySender class=org.nuxeo.mail.JndiSMTPMailSender>
      <property name=jndiSessionName>mySessionName</property>
    </sender>

  </extension>
</component>

 More on JIRA ticket NXP-32029

Install ARM Compatible Tools in Nuxeo Docker Image

The Nuxeo 2023 Docker image (docker-private.packages.nuxeo.com/nuxeo/nuxeo:2023) supports multiple platforms: it contains variants for the amd64 (x86) and arm64v8 architectures.

When pulling this image, Docker automatically selects the variant that matches your OS and architecture. For instance, if you're running on:

  • Linux (AMD64), you'll get the amd64 variant.
  • Apple Silicon M1 (ARM64), you'll get the arm64 variant.

The arm64 variant doesn't include the LibreOffice converter. Unfortunately, there is currently no LibreOffice RPM package available in a recent version for Rocky Linux (the base OS) in the arm64 architecture.

Consequently, the arm64 variant of the Nuxeo 2023 Docker image is not production-ready. It is for development purpose only.

Note that you can force the target platform when pulling or running the Docker image with the --platform option, for instance to pull the amd64 variant:

docker pull docker-private.packages.nuxeo.com/nuxeo/nuxeo:2023 --platform=linux/amd64

The Nuxeo 2021 Docker image isn't impacted by this change, it only supports the amd64 architecture.

 More on JIRA ticket NXP-31815

Hotfix 3

Orphan Version Full GC Is Not Working With orphanVersionRemovalFilter Contributions

On 2023 the contribution org.nuxeo.ecm.core.event.orphanVersionRemoval.listener has been removed.

 More on JIRA ticket NXP-32073

Hotfix 1

Add Flexible Record Core API

When using the Retention package with a MongoDB backend, it is recommended to create new indexes manually, otherwise, the Nuxeo server will attempt to create them at start-up. In the case of an existing instance with large amounts of documents, this process may time out and/or affect performance.

db.default.createIndex({ ecm:isRecord: 1}, {sparse: true});
db.default.createIndex({ ecm:isFlexibleRecord: 1}, {sparse: true});

 More on JIRA ticket NXP-31968

Rename Compliance Mode as Strict Mode

The nuxeo.conf property nuxeo.retention.compliance.enabled has been deprecated in favor of nuxeo.retention.strictmode.enabled. When both properties are configured, nuxeo.retention.strictmode.enabled takes precedence.

 More on JIRA ticket NXP-31878