This is an automated email from the ASF dual-hosted git repository.

ppkarwasz pushed a commit to branch doc/build-lifecycle
in repository https://gitbox.apache.org/repos/asf/logging-parent.git

commit fea04d02f231d3992d3d155e9730c6e08375d285
Author: Piotr P. Karwasz <[email protected]>
AuthorDate: Fri Jul 3 20:51:02 2026 +0200

    Document the build lifecycle and troubleshooting
    
    Add two Antora pages describing what the Logging Parent POM adds to the
    Maven build:
    
    - `build-lifecycle.adoc`: the checks, generated artifacts, and POM
      transformations bound to `./mvnw verify`; the opt-in profiles (build
      modifiers and commands); and what is inherited from the ASF Parent POM.
    - `troubleshooting.adoc`: recipes for the two checks that are hardest to
      diagnose, the BND baseline API-compatibility check and the
      `requireUpperBoundDeps` dependency-convergence check, using real
      captured error output.
    
    Wire both pages into the site navigation under a new "Build" group.
    
    Assisted-By: Claude Opus 4.8 (1M context) <[email protected]>
---
 src/site/antora/modules/ROOT/nav.adoc              |   4 +
 .../antora/modules/ROOT/pages/build-lifecycle.adoc | 430 +++++++++++++++++++++
 .../antora/modules/ROOT/pages/troubleshooting.adoc | 168 ++++++++
 3 files changed, 602 insertions(+)

diff --git a/src/site/antora/modules/ROOT/nav.adoc 
b/src/site/antora/modules/ROOT/nav.adoc
index 513c689..a32360a 100644
--- a/src/site/antora/modules/ROOT/nav.adoc
+++ b/src/site/antora/modules/ROOT/nav.adoc
@@ -20,6 +20,10 @@
 * xref:workflows.adoc[]
 * xref:release-notes.adoc[]
 
+.Build
+* xref:build-lifecycle.adoc[]
+* xref:troubleshooting.adoc[]
+
 .Release support
 * xref:release-review-instructions.adoc[]
 * xref:release-instructions-project.adoc[]
diff --git a/src/site/antora/modules/ROOT/pages/build-lifecycle.adoc 
b/src/site/antora/modules/ROOT/pages/build-lifecycle.adoc
new file mode 100644
index 0000000..e8d532a
--- /dev/null
+++ b/src/site/antora/modules/ROOT/pages/build-lifecycle.adoc
@@ -0,0 +1,430 @@
+////
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+////
+
+:asf-parent-url: https://maven.apache.org/pom/asf/
+
+[#build-lifecycle]
+= Build lifecycle
+
+{project-name} extends the standard Maven _default_ (build) lifecycle that 
runs on a plain
+
+[source,bash]
+----
+./mvnw verify
+----
+
+with three kinds of additions:
+
+* <<checks>> that fail the build when a rule is violated,
+* <<artifacts>> that are generated and attached or embedded into your JARs, and
+* <<transformations>> applied to the POM before it is published.
+
+Some of these additions come from {project-name} itself, some are inherited 
from the
+{asf-parent-url}[ASF Parent POM], and some are activated only when a 
particular _activator file_ is present in your project.
+Each origin is called out below.
+
+Beyond a plain `./mvnw verify`, the parent also offers two opt-in mechanisms:
+
+* <<optional-extensions>> that you enable on the command line to modify a 
build, and
+* <<commands>> whose default goal performs a single task on its own.
+
+[#phase-map]
+== Overview
+
+The following table maps each addition to the Maven phase it binds to.
+Everything listed here is triggered by a plain `./mvnw verify`, unless it is 
marked as conditional on an activator file.
+
+[cols="2m,2,5a",options="header"]
+|===
+| Phase | Origin | Additions
+
+| validate
+| {asf-parent-url}[ASF Parent POM]
+|
+* <<check-build-environment>>
+
+| validate
+| {project-name}
+|
+* <<check-dependency-convergence>>
+* <<check-code-style>> _(no wildcard imports)_
+* <<check-changelog>>
+
+| generate-resources
+| {asf-parent-url}[ASF Parent POM]
+|
+* <<artifacts-asf>>
+
+| process-resources
+| {project-name}
+|
+* <<transformations-pom>>
+
+| compile
+| {project-name}
+|
+* <<check-static-analysis>> _(ErrorProne)_
+
+| process-classes
+| {project-name}
+|
+* <<artifacts-osgi>>
+* <<artifacts-jpms>>
+* <<artifacts-services>>
+
+| package
+| {project-name}
+|
+* <<artifacts-sbom,CycloneDX SBOM>>
+
+| verify
+| {project-name}
+|
+* <<check-code-style>> (Spotless)
+* <<check-license>>
+* <<check-static-analysis>> _(SpotBugs + FindSecBugs)_
+* <<check-api-compatibility,API compatibility (BND baseline)>>
+|===
+
+[#checks]
+== Additional checks
+
+The checks below run automatically during `./mvnw verify`.
+The trickier ones link to a debugging recipe in xref:troubleshooting.adoc[].
+
+[#check-build-environment]
+=== Maven & Java version
+
+_Phase:_ `validate`.
+_Enforced by the {asf-parent-url}[ASF Parent POM]._
+
+To build an Apache Logging Services project you need:
+
+* a *JDK 17* (the build pins the major version `17`, not a later one), and
+* *Maven 3.8.1 or later*, most conveniently through the bundled Maven Wrapper 
(`./mvnw`).
+
+Both requirements are checked by the `maven-enforcer-plugin` inherited from 
the ASF Parent POM, through its `requireJavaVersion` and `requireMavenVersion` 
rules.
+These rules can be modified using the properties below:
+
+[cols="2m,3,1m",options="header"]
+|===
+| Property | Controls | Default
+
+| minimalJavaBuildVersion
+| Range of JDK versions allowed to run the build
+| {java-compiler-version}
+
+| minimalMavenBuildVersion
+| Range of Maven versions allowed to run the build
+| 3.8.1
+
+| maven.compiler.release
+| Java bytecode level the sources are compiled to
+| 8
+|===
+
+Although most artifacts still target Java 8 bytecode (through the `javac 
--release 8` flag), JDK 17 is required to run the Maven plugins in use and to 
keep builds reproducible.
+Bytecode generation can differ between JDK major versions, so pinning a single 
one keeps the output byte-for-byte stable.
+
+[NOTE]
+====
+JDK 17 also requires the `--add-exports` and `--add-opens` flags declared in 
`.mvn/jvm.config`, needed by tools that reach into JDK compiler internals (such 
as Error Prone).
+See xref:usage.adoc[].
+====
+
+Some projects (currently only Log4j) additionally run their test suites 
against a real *JDK 8* through
+https://maven.apache.org/guides/mini/guide-using-toolchains.html[Maven 
Toolchains]
+in CI.
+This proves runtime compatibility with the Java 8 platform, beyond the 
bytecode and API-surface guarantees that `--release 8` provides on its own.
+
+[#check-dependency-convergence]
+=== Order-independent dependency resolution
+
+_Phase:_ `validate`.
+
+Maven's default conflict _mediation_ (nearest-wins, ties broken by declaration 
order) can resolve a dependency to a version _lower_ than some transitive 
dependency requires, and the outcome can shift when dependencies are reordered.
+The `maven-enforcer-plugin` `requireUpperBoundDeps` rule forbids this: it 
fails whenever a resolved version is lower than the highest one required across 
the graph.
+
+The fix is to pin that dependency to at least the highest required version, 
making resolution order-independent.
+See xref:troubleshooting.adoc#require-upper-bound-deps[the Order-independent 
dependency resolution recipe] for how to read the error and adjust the pin.
+
+[IMPORTANT]
+====
+Pinning a transitive dependency in your `<dependencyManagement>` only affects 
_your_ build.
+It has *no* influence on the versions resolved by downstream consumers of your 
artifacts.
+====
+
+[#check-code-style]
+=== Code style
+
+Code style is enforced by the `spotless-maven-plugin` in the `verify` phase, 
with one exception: the ban on wildcard imports is a `maven-enforcer-plugin` 
rule that runs earlier, in the `validate` phase.
+The following rules apply:
+
+All files::
++
+Line endings are normalized to UNIX (`LF`) and the ASF license header is 
required.
+Set a `.gitattributes` file so that Git checks files out with `LF` on every 
platform.
+
+Java::
++
+Sources follow the
+https://github.com/palantir/palantir-java-format[Palantir Java format], and 
imports must be explicit (wildcard imports are banned).
+
+XML, POM, `.properties` & YAML::
++
+`pom.xml` is sorted with the Spotless 
https://github.com/Ekryd/sortpom[sortPom] step; XML and YAML files also have 
trailing whitespace trimmed and a final newline enforced.
+
+Most violations are fixed automatically by:
+
+[source,bash]
+----
+./mvnw spotless:apply
+----
+
+Anything the formatter cannot fix must be corrected by hand.
+
+[NOTE]
+====
+The Spotless configuration must stay in sync with the project's 
`.editorconfig`.
+====
+
+[#check-changelog]
+=== Changelog validation
+
+_Phase:_ `validate`.
+_Activated by `src/changelog/`._
+
+Apache Logging Services projects track their release notes as individual XML 
files under `src/changelog/`, managed by the 
https://github.com/apache/logging-log4j-tools/tree/main/log4j-changelog-maven-plugin[`log4j-changelog-maven-plugin`].
+When that directory is present, the `xml-maven-plugin` validates every entry 
against the Log4j Changelog schema, so a malformed entry fails the build early 
instead of breaking release-note generation later.
+
+The schema is documented on the 
{logging-services-url}/xml/ns/#log4j-changelog[Log4j XML schema page].
+
+[#check-static-analysis]
+=== Static analysis
+
+Two static analysis tools scan the code on every build.
+
+Error Prone::
++
+_Phase:_ `compile`.
+Bundled into the `maven-compiler-plugin` (alongside `-Xlint:all`), it catches 
common Java mistakes as the code compiles.
+Its checks are fixed by {project-name} and are not configurable per project.
+
+SpotBugs + FindSecBugs::
++
+_Phase:_ `verify`.
+The `spotbugs-maven-plugin` runs SpotBugs together with the 
https://find-sec-bugs.github.io/[FindSecBugs] plugin for security-oriented bug 
patterns.
+False positives can be suppressed by adding a `spotbugs-exclude.xml` file to 
the project root; its presence alone activates the exclusion filter.
+
+[#check-license]
+=== License validation
+
+_Phase:_ `verify`.
+
+The https://creadur.apache.org/rat[`apache-rat-plugin`] verifies that the 
project complies with the
+https://www.apache.org/legal/src-headers.html[ASF Source Header and Copyright 
Notice Policy], failing the build when a file is missing the required ASF 
license header.
+
+Files that legitimately cannot carry a header or have been exempted from 
carrying one have been added to an exclude list.
+
+[#check-api-compatibility]
+=== API compatibility
+
+_Phase:_ `verify`.
+
+Public APIs must not change without an *explicit* version bump.
+The `bnd-baseline-maven-plugin` compares each module's exported packages 
against their last release and enforces 
https://docs.osgi.org/whitepaper/semantic-versioning/[OSGi semantic 
versioning]: a backward-compatible addition needs a _minor_ increment, a 
breaking change a _major_ one, and an internal-only fix a _micro_ one.
+Package versions are declared with the `@Version` annotation in each package's 
`package-info.java`.
+
+When a change is not matched by the right increment, the build fails with a 
table reporting the detected _delta_ (`MICRO`, `MINOR`, or `MAJOR`) and the 
version the plugin suggests.
+The rules for choosing the increment, and how to resolve such a failure, are 
explained in xref:troubleshooting.adoc#bnd-baseline[the API compatibility 
recipe].
+
+[#artifacts]
+== Additional generated artifacts
+
+Beyond the main JAR, the build attaches or embeds the following.
+
+[#artifacts-osgi]
+=== OSGi manifest
+
+_Phase:_ `process-classes`.
+
+The `bnd-maven-plugin` generates an OSGi `META-INF/MANIFEST.MF` and hands it 
to the `maven-jar-plugin`, which packages it instead of its own default 
manifest.
+BND derives the manifest from the compiled bytecode:
+
+* `Bundle-SymbolicName` is computed from the `groupId` and `artifactId`;
+* `Export-Package` lists the packages annotated with 
`org.osgi.annotation.bundle.Export` in their `package-info.java`;
+* `Import-Package` is inferred from the packages the code actually references.
+
+This automatic inference is correct in the vast majority of cases, but a few 
situations must be declared explicitly, for example an _optional_ dependency, 
whose import BND marks as mandatory unless told otherwise.
+Such cases can be tuned through the following properties, without redefining 
the whole BND configuration:
+
+[cols="2m,4,2",options="header"]
+|===
+| Property | Purpose | Default
+
+| bnd-extra-package-options
+| Extra `Import-Package` instructions.
+| _(empty)_
+
+| bnd-bundle-symbolicname
+| Override the computed `Bundle-SymbolicName`
+| derived from `groupId` and `artifactId`
+
+| bnd-multi-release
+| Value of the `Multi-Release` manifest header
+| `false`
+
+| bnd-extra-config
+| Arbitrary extra BND instructions, appended last.
+| _(empty)_
+|===
+
+For the full set of `bnd-*` properties and worked examples, see 
xref:usage.adoc[].
+
+[#artifacts-jpms]
+=== JPMS module descriptor
+
+_Phase:_ `process-classes`.
+
+The same `bnd-maven-plugin` execution that produces the <<artifacts-osgi,OSGi 
manifest>> also synthesizes a JPMS `module-info` descriptor from the same 
metadata.
+This gives each module a proper, stable module name and its `requires`, 
`exports`, `provides`, and `uses` directives without a hand-written 
`module-info.java`, which could not target Java 8 anyway.
+
+The module name defaults to the `Bundle-SymbolicName`, and the `requires` 
directives are inferred from the imported packages.
+When that inference needs adjusting, use the following properties:
+
+[cols="2m,4,1",options="header"]
+|===
+| Property | Purpose | Default
+
+| bnd-module-name
+| Override the generated JPMS module name
+| the `Bundle-SymbolicName`
+
+| bnd-extra-module-options
+| Refine the computed `requires` directives (see the 
https://bnd.bndtools.org/chapters/330-jpms.html#advanced-options[BND JPMS 
options]); use only when `bnd-extra-package-options` cannot express the change
+| _(empty)_
+|===
+
+[TIP]
+====
+To keep incremental recompiles working, a `maven-clean-plugin` execution 
deletes any stale
+`module-info.class` from the output directory before each compilation.
+This works around a `javac` limitation and is not something you need to 
configure.
+
+The same deletion, however, makes the classes folder look modified on every 
invocation.
+Use `-Dbnd.skip` to suppress the BND processing when you do not need to modify 
the descriptors.
+====
+
+[#artifacts-services]
+=== ServiceLoader descriptor
+
+_Phase:_ `process-classes`.
+
+`java.util.ServiceLoader` requires a provider-registration file under 
`META-INF/services/` and, on the module path, matching `provides` and `uses` 
directives in `module-info`.
+Rather than maintaining these by hand, {project-name} lets BND generate them 
from two annotations:
+
+`aQute.bnd.annotation.spi.ServiceProvider`::
++
+Placed on a service _implementation_, it registers the class in the 
appropriate `META-INF/services/<service>` file and adds a `provides <service> 
with <implementation>` directive to the JPMS descriptor.
+
+`aQute.bnd.annotation.spi.ServiceConsumer`::
++
+Placed on a type that looks services up through `ServiceLoader`, it adds the 
matching `uses <service>` directive to the JPMS descriptor.
+
+Driving both the class-path (`META-INF/services/`) and module-path 
(`module-info`) registrations from a single annotation keeps the two 
representations from drifting apart.
+
+[#artifacts-sbom]
+=== CycloneDX SBOM
+
+_Phase:_ `package`.
+
+The `cyclonedx-maven-plugin` generates a
+https://cyclonedx.org/capabilities/vdr[CycloneDX Software Bill of Materials 
(SBOM)] for every module, describing its resolved dependencies.
+Each SBOM is attached as an XML artifact with the `cyclonedx` classifier 
(`<artifactId>-<version>-cyclonedx.xml`) and carries a 
`vulnerability-assertion` external reference to the shared Apache Logging 
Services VDR.
+See xref:features.adoc#cyclonedx-sbom[] for details.
+
+[#artifacts-asf]
+=== Embedded LICENSE, NOTICE, and DEPENDENCIES
+
+_Phase:_ `generate-resources`.
+
+The `maven-remote-resources-plugin`, configured by the {asf-parent-url}[ASF 
Parent POM] and its shared resource bundle, contributes three files under the 
`META-INF/` directory of every produced JAR:
+
+`META-INF/LICENSE`:: the Apache License 2.0 text;
+`META-INF/NOTICE`:: the artifact's attribution notices;
+`META-INF/DEPENDENCIES`:: a list of the module's transitive dependencies, 
grouped by organization and annotated with their licenses.
+
+`META-INF/DEPENDENCIES` is always generated from the resolved dependency tree.
+`META-INF/LICENSE` and `META-INF/NOTICE`, on the other hand, are only 
_defaults_: a module's own `src/main/resources/META-INF/LICENSE` or 
`META-INF/NOTICE` takes precedence, so a module that records third-party 
attributions ships its curated files instead of the generated ones.
+
+[#transformations]
+== Artifact transformations
+
+[#transformations-pom]
+=== POM flattening
+
+_Phase:_ `process-resources`.
+
+The POM you write is not the POM that gets published.
+{project-name} uses 
https://maven.apache.org/maven-ci-friendly.html[CI-friendly versioning], so the 
project version is the `$\{revision}` property, and a POM still holding an 
unresolved `$\{revision}` is not consumable by Maven.
+The `flatten-maven-plugin` therefore rewrites the POM into a 
`.flattened-pom.xml`, which is the file actually installed and deployed.
+The rewrite runs in one of two modes:
+
+Default (`resolveCiFriendliesOnly`)::
++
+Only the CI-friendly properties (`$\{revision}` and friends) are resolved; the 
rest of the POM, including its `parent`, is preserved as-is.
+
+BOM (`bom`)::
++
+_Activated by `.logging-parent-bom-activator`._
+The POM is reduced to a self-contained Bill of Materials: besides resolving 
the version, the `parent`, `build`, `properties`, and `profiles` sections are 
removed, leaving only the managed dependencies.
+This keeps consumers of the BOM free of unrelated build configuration.
++
+A BOM must therefore *not* reference a property defined solely in an ancestor 
POM: `bom`-mode interpolation resolves variables from the module's own POM 
only, so an inherited property would be left unresolved after flattening.
+
+[#optional-extensions]
+== Optional lifecycle extensions
+
+The following profiles are not activated automatically; you enable them on the 
command line to add behavior to an otherwise normal build.
+
+`-Prelease`::
+Generates the additional artifacts a release requires: it attaches the 
`-sources` JAR and enforces that neither the project version nor any of its 
dependencies is a SNAPSHOT.
++
+NOTE: Apache Logging Service projects do *not* use the ASF Parent POM's 
`apache-release` profile; this `release` profile, together with the `deploy` or 
`distribution` commands, replace it.
+
+`-Pcoverage`::
+Runs the `jacoco-maven-plugin` to collect test coverage during the build and 
write an HTML report under `target/site/jacoco`.
+
+`-Dapache.snapshots`::
+Activates the ASF Parent POM's `use-apache-snapshots` profile, adding the 
https://repository.apache.org/snapshots[Apache snapshots repository].
+It lets you build only some modules of a project and resolve the rest from the 
regularly published SNAPSHOT artifacts, instead of building every upstream 
module locally.
+
+[#commands]
+== Additional commands
+
+A few profiles are not lifecycle extensions but _commands_: each carries a 
`defaultGoal`, so enabling the profile without naming a phase runs a single 
task and nothing else.
+They are normally invoked by the reusable deployment workflows, but can also 
be run by hand.
+
+`./mvnw -Pchangelog-release`::
+Moves the pending changelog entries from `src/changelog/.<version>.x.x/` into 
the released version's directory and regenerates the release notes.
+
+`./mvnw -Pdistribution`::
+Builds the source (`src.zip`) and binary (`bin.zip`) distribution archives 
from the Git-tracked files.
+Requires the `attachmentFilepathPattern` and `attachmentCount` properties and 
a prior `package`.
+
+`./mvnw -Pdeploy`::
+Signs the artifacts and deploys them to the Apache Nexus staging repository 
via the `nexus-staging-maven-plugin` (skipping tests, SpotBugs, and Spotless).
diff --git a/src/site/antora/modules/ROOT/pages/troubleshooting.adoc 
b/src/site/antora/modules/ROOT/pages/troubleshooting.adoc
new file mode 100644
index 0000000..ef7851d
--- /dev/null
+++ b/src/site/antora/modules/ROOT/pages/troubleshooting.adoc
@@ -0,0 +1,168 @@
+////
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+////
+
+[#troubleshooting]
+= Troubleshooting
+
+This page collects debugging recipes for the build checks that are not 
self-explanatory.
+
+[#bnd-baseline]
+== API compatibility (BND baseline)
+
+The xref:build-lifecycle.adoc#check-api-compatibility[API compatibility check] 
(`bnd-baseline-maven-plugin`) fails a build when the public API of a module 
changed in a way that is not reflected in its version numbers.
+When it trips, `./mvnw verify` prints a report (also written to 
`target/baseline/<artifactId>-<version>.txt`) similar to:
+
+[source]
+----
+===============================================================
+  Name                             Type     Delta     New              Old     
 Suggest
+  org.apache.logging.log4j.api     BUNDLE   MAJOR     2.27.0.SNAPSHOT  2.26.1  
 -
+===============================================================
+  Name                             Type     Delta     New       Old      
Suggest  If Prov.
+* org.apache.logging.log4j         PACKAGE  MINOR     2.20.2    2.20.2   
2.21.0   -
+  MINOR              PACKAGE    org.apache.logging.log4j
+    MINOR            CLASS      org.apache.logging.log4j.MarkerManager
+      ADDED          METHOD     triggerBaselineError()
+        ADDED        ACCESS     static
+        ADDED        RETURN     int
+  org.apache.logging.log4j.message PACKAGE  UNCHANGED 2.24.2    2.24.2   ok    
   -
+  ...
+----
+
+Read it as follows:
+
+* The rows marked with `*` are the ones you must fix.
+* `Delta` is the kind of change BND detected in that package: `MICRO`, 
`MINOR`, or `MAJOR`.
+* `Old` is the version of the package in the last release, `New` is the 
version you currently declare.
+* `Suggest` is the *minimal* version that would satisfy the detected change.
++
+[IMPORTANT]
+====
+The `Suggest` value is only BND's _minimal_ acceptable version; we do not 
always adopt it verbatim.
+For a `MICRO` change we follow the suggestion, but for a `MINOR` change we 
align the package version with the project version instead.
+See <<bnd-baseline-why>> for the rationale.
+====
+* The indented tree below a package explains _why_ that delta was computed 
(here, a `static` method `triggerBaselineError()` was `ADDED`).
+
+Package versions are declared with the `@Version` annotation of the package's 
`package-info.java`:
+
+[source,java]
+----
+@Version("2.20.2")
+package org.apache.logging.log4j;
+----
+
+How you resolve the failure depends on the `Delta`.
+
+[#bnd-baseline-micro]
+=== `MICRO`
+
+A change that is both binary- and source-compatible but that BND still 
detects, most commonly an annotation added to or removed from an API member and 
retained in its bytecode.
+
+Bump the *patch* component of the package version to the value in the 
`Suggest` column, *not* to the upcoming project version, by editing its 
`package-info.java`:
+
+[source,java]
+----
+@Version("2.20.3")
+package org.apache.logging.log4j;
+----
+
+Here we keep the suggested `2.20.3`, regardless of the upcoming project 
version; see <<bnd-baseline-why>>.
+
+[#bnd-baseline-minor]
+=== `MINOR`
+
+A backward-compatible addition to the public API: a new method, class, field, 
or constant.
+In the report above, adding the `triggerBaselineError()` method produced a 
`MINOR` delta on `org.apache.logging.log4j`.
+
+Resolve it in three steps:
+
+. *Make the project version a minor upgrade over the last release.*
+Adding API requires a new minor release, so the project version must reflect 
it.
+If the `<revision>` property is only a patch upgrade (for example 
`2.26.1-SNAPSHOT` after the `2.26.0` release), raise it to the next minor 
version (`2.27.0-SNAPSHOT`).
+. *Record the change in the changelog.*
+Add an entry of type `added` (or `changed` / `deprecated`, as appropriate) so 
the addition appears in the release notes.
+. *Bump the package version.*
+Set the `@Version` in the package's `package-info.java` to the upcoming 
project version, **not** to the minimal value in the `Suggest` column:
++
+[source,java]
+----
+@Version("2.27.0")
+package org.apache.logging.log4j;
+----
++
+Using `2.27.0` rather than the suggested `2.21.0` is deliberate; see 
<<bnd-baseline-why>>.
+
+[#bnd-baseline-major]
+=== `MAJOR`
+
+A breaking change: a public member was removed, renamed, or changed in an 
incompatible way.
+On a stable branch (for example Log4j `2.x`) this is *not* accepted, and 
bumping the package major version is not an option.
+
+Instead of changing the version, rework the change so that it stays 
backward-compatible, for example by deprecating a member instead of removing 
it, or by adding an overload instead of altering an existing signature.
+
+If you are convinced the report is a false positive (for example, the member 
you removed was documented as private), ask the development team before 
overriding the check.
+
+[#bnd-baseline-why]
+=== Why these rules?
+
+These conventions make a package's `@Version` tell you, at a glance, when its 
public API last changed.
+
+Because a `MINOR` change sets the package version to the project version, 
while a `MICRO` change only increments the patch component, a package version 
such as `2.34.5` reads as:
+
+* its public API last changed in release `2.34.0`, and
+* `5` smaller, API-compatible revisions have been published since.
+
+Had we used BND's minimal `Suggest` value instead, the minor component would 
not line up with any release, and the version would carry no such meaning.
+
+[#require-upper-bound-deps]
+== Order-independent dependency resolution
+
+The xref:build-lifecycle.adoc#check-dependency-convergence[Order-independent 
dependency resolution check] (the `maven-enforcer-plugin` 
`requireUpperBoundDeps` rule) fails when the version Maven resolves for a 
dependency is lower than a version required elsewhere in the graph.
+
+A failure looks like this:
+
+[source]
+----
+Rule 0: ...RequireUpperBoundDeps failed with message:
+Failed while enforcing RequireUpperBoundDeps. The error(s) are [
+Require upper bound dependencies error for commons-codec:commons-codec:1.10. 
Paths to dependency are:
++-test:upperbound-test:1.0
+  +-commons-codec:commons-codec:1.10
+and
++-test:upperbound-test:1.0
+  +-org.apache.httpcomponents:httpclient:4.5.13
+    +-commons-codec:commons-codec:1.11
+]
+----
+
+Read it as follows:
+
+* The header names the *resolved* version that is too low 
(`commons-codec:1.10`).
+* Each `Paths to dependency` block is one route through the tree.
+The first route shows how the low version was selected (here `commons-codec` 
is declared directly); the others show who requires a higher version 
(`httpclient:4.5.13` needs `1.11`).
+
+To fix it, find where the too-low version is defined, usually in the project's 
parent POM, where all dependency versions are managed.
+
+If the parent POM does *not* pin `commons-codec`::
+Add it to the parent's `<dependencyManagement>` at a version at least as high 
as the highest one required (`1.11` here).
+
+If the parent POM already pins `commons-codec`::
+The pin is what forced the lower version, so it is the cause of the failure.
+Bump it to at least the required minimum (`1.11`).
++
+It is also worth trying to *remove* the pin altogether: the direct 
dependencies that once needed it may have since upgraded to mutually compatible 
versions, making the pin unnecessary.

Reply via email to