Chapter 7. Patching Red Hat Fuse application
Using the new patch-maven-plugin
mechanism you can apply a patch to your Red Hat Fuse application. This mechanism allows you to change the individual versions provided by different Red Hat Fuse BOMS, for example, fuse-springboot-bom
and fuse-karaf-bom
.
7.1. About patch-maven-plugin
The patch-maven-plugin
performs following operations:
- Retrieve the patch metadata related to current Red Hat Fuse BOMs.
-
Apply the version changes to
<dependencyManagement>
imported from the BOMs.
After the patch-maven-plugin
fetches the metadata, it iterates through all managed and direct dependencies of the project where the plugin was declared and replaces the dependency versions (if they match) using CVE/patch metadata. After versions are replaced, Maven build continues and progresses through standard Maven project stages.
7.2. Applying patch to Red Hat Fuse applications
The purpose of patch-maven-plugin is to update the versions of the dependencies listed in the Red Hat Fuse BOM to the versions specified in the patch metadata of the patch that you wish to apply to your applications.
Procedure
Following procedure explains how to apply the patch to your application.
Add
patch-maven-plugin
to your project’spom.xml
file. The version of thepatch-maven-plugin
must be the same as the version of the Fuse BOM.<build> <plugins> <plugin> <groupId>org.jboss.redhat-fuse</groupId> <artifactId>patch-maven-plugin</artifactId> <version>${version.org.jboss-redhat-fuse}</version> <extensions>true</extensions> </plugin> </plugins> </build>
When you run any one of the
mvn clean deploy
ormvn validate
ormvn dependency:tree
commands, the plugin searches through the project modules to check whether one of Red Hat Fuse BOMs is used. Only two are considered as the supported BOMs:-
org.jboss.redhat-fuse:fuse-karaf-bom
: for Fuse Karaf BOM -
org.jboss.redhat-fuse:fuse-springboot-bom
: for Fuse Spring Boot BOM
-
If none of the above BOMs are found, the plugin will display following messages:
$ mvn clean install [INFO] Scanning for projects... [INFO] ========== Red Hat Fuse Maven patching ========== [INFO] [PATCH] No project in the reactor uses Fuse Karaf or Fuse Spring Boot BOM. Skipping patch processing. [INFO] [PATCH] Done in 3ms
If both Fuse BOMs are found, the
patch-maven-plugin
stops with the following warning:$ mvn clean install [INFO] Scanning for projects... [INFO] ========== Red Hat Fuse Maven patching ========== [WARNING] [PATCH] Reactor uses both Fuse Karaf and Fuse Spring Boot BOMs. Please use only one. Skipping patch processing. [INFO] [PATCH] Done in 3ms
The
patch-maven-plugin
attempts to fetch one of the following Maven metadata values.-
For the projects with Fuse Karaf BOM, the
org.jboss.redhat-fuse/fuse-karaf-patch-metadata/maven-metadata.xml
is resolved. This is the metadata for the artifact with theorg.jboss.redhat-fuse:fuse-karaf-patch-metadata:RELEASE
coordinates. For the projects with Fuse Spring Boot BOM project, the
org.jboss.redhat-fuse/fuse-springboot-patch-metadata/maven-metadata.xml
is resolved. This is the metadata for the artifact with theorg.jboss.redhat-fuse:fuse-springboot-patch-metadata:RELEASE
coordinates.Example metadata generated by Maven
<?xml version="1.0" encoding="UTF-8"?> <metadata> <groupId>org.jboss.redhat-fuse</groupId> <artifactId>fuse-springboot-patch-metadata</artifactId> <versioning> <release>7.8.1.fuse-sb2-781025</release> <versions> <version>7.8.0.fuse-sb2-780025</version> <version>7.7.0.fuse-sb2-770010</version> <version>7.7.0.fuse-770010</version> <version>7.8.1.fuse-sb2-781025</version> </versions> <lastUpdated>20201023131724</lastUpdated> </versioning> </metadata>
-
For the projects with Fuse Karaf BOM, the
-
The
patch-maven-plugin
parses the metadata to select the version which is applicable to the current project. This is possible only for the Maven projects using Fuse BOM with version 7.8.xxx. Only the metadata that matches the version range 7.8, 7.9 or later is applicable and only the latest version of the metadata is fetched. The
patch-maven-plugin
collects a list of remote Maven repositories to be used when downloading the patch metadata identified bygroupId
,artifactId
andversion
found in previous steps. These Maven repositories are the ones that are listed in the project’s<repositories>
elements in the active profiles and also the repositories fromsettings.xml
file.$ mvn clean install [INFO] Scanning for projects... [INFO] ========== Red Hat Fuse Maven patching ========== [INFO] [PATCH] Reading patch metadata and artifacts from 2 project repositories [INFO] [PATCH] - local-nexus: http://everfree.forest:8081/repository/maven-releases/ [INFO] [PATCH] - central: https://repo.maven.apache.org/maven2 Downloading from local-nexus: http://everfree.forest:8081/repository/maven-releases/org/jboss/redhat-fuse/fuse-springboot-patch-metadata/maven-metadata.xml ...
Optionally, if you wish to use a offline repository, you can use
-Dpatch
option to specify a ZIP file which is produced byfuse-karaf/fuse-karaf-patch-repository
orfuse-springboot/fuse-springboot-patch-repository
modules ofjboss-fuse/redhat-fuse
project. These ZIP files have the same internal structure as the Maven repository structure. For example,$ mvn clean install -Dpatch=../../../test/resources/patch-3.zip [INFO] Scanning for projects... [INFO] ========== Red Hat Fuse Maven patching ========== [INFO] [PATCH] Reading metadata and artifacts from /data/sources/github.com/jboss-fuse/redhat-fuse/fuse-tools/patch-maven-plugin/src/test/resources/patch-3.zip Downloading from fuse-patch: zip:file:/tmp/patch-3.zip-1742974214598205745/org/jboss/redhat-fuse/fuse-springboot-patch-metadata/maven-metadata.xml Downloaded from fuse-patch: zip:file:/tmp/patch-3.zip-1742974214598205745/org/jboss/redhat-fuse/fuse-springboot-patch-metadata/maven-metadata.xml (406 B at 16 kB/s) Downloading from fuse-patch: zip:file:/tmp/patch-3.zip-1742974214598205745/org/jboss/redhat-fuse/fuse-springboot-patch-metadata/7.8.0.fuse-sb2-781023/fuse-springboot-patch-metadata-7.8.0.fuse-sb2-781023.xml Downloaded from fuse-patch: zip:file:/tmp/patch-3.zip-1742974214598205745/org/jboss/redhat-fuse/fuse-springboot-patch-metadata/7.8.0.fuse-sb2-781023/fuse-springboot-patch-metadata-7.8.0.fuse-sb2-781023.xml (926 B at 309 kB/s) [INFO] [PATCH] Resolved patch descriptor: /home/user/.m2/repository/org/jboss/redhat-fuse/fuse-springboot-patch-metadata/7.8.0.fuse-sb2-781023/fuse-springboot-patch-metadata-7.8.0.fuse-sb2-781023.xml ...
Whether the metadata comes from remote repository, local repository or ZIP file, it is analyzed by the
patch-maven-plugin
. The fetched metadata contains list of CVEs and for each CVE we have a list of affected Maven artifacts (specified by glob patterns and version ranges) together with a version that contains a fix for a given CVE. For example,<?xml version="1.0" encoding="UTF-8" ?> <metadata xmlns="urn:redhat:fuse:patch-metadata:1"> <product-bom groupId="org.jboss.redhat-fuse" artifactId="fuse-springboot-bom" versions="[7.8,7.9)" /> <cves> <cve id="CVE-2020-xyz" description="Jetty can be configured to listen on port 8080" cve-link="https://nvd.nist.gov/vuln/detail/CVE-2020-xyz" bz-link="https://bugzilla.redhat.com/show_bug.cgi?id=42"> <affects groupId="org.eclipse.jetty" artifactId="jetty-*" versions="[9.4,9.4.32)" fix="9.4.32.v20200930" /> <affects groupId="org.eclipse.jetty.http2" artifactId="http2-*" versions="[9.4,9.4.32)" fix="9.4.32.v20200930" /> </cve> </cves> <fixes /> </metadata>
Finally a list of fixes specified in patch metadata is consulted when iterating over all managed dependencies in current project. These dependencies (and managed dependencies) that match are changed to fixed versions. For example:
$ mvn clean install -U [INFO] Scanning for projects... [INFO ========== Red Hat Fuse Maven patching ========== [INFO] [PATCH] Reading patch metadata and artifacts from 2 project repositories [INFO] [PATCH] - local-nexus: http://everfree.forest:8081/repository/maven-releases/ [INFO] [PATCH] - central: https://repo.maven.apache.org/maven2 Downloading from local-nexus: http://everfree.forest:8081/repository/maven-releases/org/jboss/redhat-fuse/fuse-springboot-patch-metadata/maven-metadata.xml Downloading from central: https://repo.maven.apache.org/maven2/org/jboss/redhat-fuse/fuse-springboot-patch-metadata/maven-metadata.xml Downloaded from local-nexus: http://everfree.forest:8081/repository/maven-releases/org/jboss/redhat-fuse/fuse-springboot-patch-metadata/maven-metadata.xml (363 B at 4.3 kB/s) [INFO] [PATCH] Resolved patch descriptor: /home/user/.m2/repository/org/jboss/redhat-fuse/fuse-springboot-patch-metadata/7.8.0.fuse-sb2-780032/fuse-springboot-patch-metadata-7.8.0.fuse-sb2-780032.xml [INFO] [PATCH] Patch metadata found for org.jboss.redhat-fuse/fuse-springboot-bom/[7.8,7.9) [INFO] [PATCH] - patch contains 1 CVE fix [INFO] [PATCH] Processing managed dependencies to apply CVE fixes... (https://nvd.nist.gov/vuln/detail/CVE-2020-xyz, https://bugzilla.redhat.com/show_bug.cgi?id=42_ [INFO] [PATCH] - CVE-2020-xyz: Jetty can be configured to expose itself on port 8080 [INFO] [PATCH] Applying change org.eclipse.jetty/jetty-*/[9.4,9.4.32) -> 9.4.32.v20200930 [INFO] [PATCH] - managed dependency: org.eclipse.jetty/jetty-alpn-client/9.4.30.v20200611 -> 9.4.32.v20200930 ... [INFO] [PATCH] - managed dependency: org.eclipse.jetty/jetty-openid/9.4.30.v20200611 -> 9.4.32.v20200930 [INFO] [PATCH] Applying change org.eclipse.jetty.http2/http2-*/[9.4,9.4.32) -> 9.4.32.v20200930 [INFO] [PATCH] - managed dependency: org.eclipse.jetty.http2/http2-client/9.4.30.v20200611 -> 9.4.32.v20200930 ... [INFO] [PATCH] Done in 635ms =================================================
Skipping the patch
In case when you do not wish to apply a specific patch to your project, the patch-maven-plugin
provides a skip
option. Assuming that you have already added patch-maven-plugin
to project’s pom.xml
file, and you don’t wish for the versions to be altered, you can use one of the following method to skip the patch.
-
Add the skip option to your project’s
pom.xml
file as follows.
<build> <plugins> <plugin> <groupId>org.jboss.redhat-fuse</groupId> <artifactId>patch-maven-plugin</artifactId> <version>${version.org.jboss-redhat-fuse}</version> <extensions>true</extensions> <configuration> <skip>true</skip> </configuration> </plugin> </plugins> </build>
-
Or use
-DskipPatch
option when running themvn
command as follows.
$ mvn dependency:tree -DskipPatch [INFO] Scanning for projects... [INFO] [INFO] ------< org.jboss.redhat-fuse:cve-dependency-management-module1 >------- [INFO] Building cve-dependency-management-module1 7.8.0.fuse-sb2-780033 [INFO] --------------------------------[ jar ]--------------------------------- ...
As shown in the above output, the patch-maven-plugin
was not invoked, which results in the patch not being applied to the application.