Troubleshooting
This page collects debugging recipes for the build checks that are not self-explanatory.
The version numbers x.y.z and a.b.c used on this page are placeholders for the project version and a package version, with increments written as x.y+1.0 or a.b.c+1.
Real build output contains concrete versions instead.
|
API compatibility (BND baseline)
The 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:
===============================================================
Name Type Delta New Old Suggest
org.apache.logging.log4j.api BUNDLE MAJOR x.y+1.0.SNAPSHOT x.y.z -
===============================================================
Name Type Delta New Old Suggest If Prov.
* org.apache.logging.log4j PACKAGE MINOR a.b.c a.b.c a.b+1.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 d.e.f d.e.f ok -
...
Read it as follows:
-
The rows marked with
*are the ones you must fix. -
Deltais the kind of change BND detected in that package:MICRO,MINOR, orMAJOR. -
Oldis the version of the package in the last release,Newis the version you currently declare. -
Suggestis the minimal version that would satisfy the detected change.The
Suggestvalue is only BND’s minimal acceptable version; we do not always adopt it verbatim. For aMICROchange we follow the suggestion, but for aMINORchange we align the package version with the project version instead. See Why these rules? for the rationale. -
The indented tree below a package explains why that delta was computed (here, a
staticmethodtriggerBaselineError()wasADDED).
Package versions are declared with the @Version annotation of the package’s package-info.java:
@Version("a.b.c")
package org.apache.logging.log4j;
How you resolve the failure depends on the Delta.
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:
@Version("a.b.c+1")
package org.apache.logging.log4j;
Here we keep the suggested a.b.c+1, regardless of the upcoming project version; see Why these rules?.
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 examplex.y.1-SNAPSHOTafter thex.y.0release), raise it to the next minor version (x.y+1.0-SNAPSHOT). -
Record the change in the changelog. Add an entry of type
added(orchanged/deprecated, as appropriate) to the pending changelog directorysrc/changelog/.<major>.x.x/, so the addition appears in the release notes. -
Bump the package version. Set the
@Versionin the package’spackage-info.javato the upcoming project version, not to the minimal value in theSuggestcolumn:@Version("x.y+1.0") package org.apache.logging.log4j;Using the project version
x.y+1.0rather than the suggesteda.b+1.0is deliberate; see Why these rules?.
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.
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 a.b.c reads as:
-
its public API last changed in release
a.b.0, and -
csmaller, 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.
Order-independent dependency resolution
The 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:
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 dependencyblock is one route through the tree. The first route shows how the low version was selected (herecommons-codecis declared directly); the others show who requires a higher version (httpclient:4.5.13needs1.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.11here). - 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.