Skip to content

Commit 90b65e8

Browse files
Copilotslachiewicz
andauthored
Document POM inheritance for banDuplicateClasses using combine.children (#341)
--------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com>
1 parent a625ab6 commit 90b65e8

File tree

6 files changed

+279
-0
lines changed

6 files changed

+279
-0
lines changed
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# Test: banDuplicateClasses Configuration Inheritance
2+
3+
This integration test demonstrates how to properly inherit and extend `banDuplicateClasses` configuration from a parent POM.
4+
5+
## Problem
6+
7+
When defining `ignoreClasses` or `dependencies` in a parent POM, child POMs cannot simply add more entries without using special Maven configuration combination attributes. By default, Maven replaces arrays/lists during POM inheritance rather than merging them.
8+
9+
## Solution
10+
11+
Use the `combine.children="append"` attribute on collection elements (`<ignoreClasses>` and `<dependencies>`) in the child POM to append to the parent's configuration.
12+
13+
### Parent POM Example
14+
15+
```xml
16+
<plugin>
17+
<artifactId>maven-enforcer-plugin</artifactId>
18+
<configuration>
19+
<rules>
20+
<banDuplicateClasses>
21+
<ignoreClasses>
22+
<ignoreClass>org.apache.commons.logging.*</ignoreClass>
23+
</ignoreClasses>
24+
<dependencies>
25+
<dependency>
26+
<groupId>commons-logging</groupId>
27+
<artifactId>commons-logging</artifactId>
28+
<ignoreClasses>
29+
<ignoreClass>org.apache.commons.logging.impl.WeakHashtable*</ignoreClass>
30+
</ignoreClasses>
31+
</dependency>
32+
</dependencies>
33+
</banDuplicateClasses>
34+
</rules>
35+
</configuration>
36+
</plugin>
37+
```
38+
39+
### Child POM Example
40+
41+
```xml
42+
<plugin>
43+
<artifactId>maven-enforcer-plugin</artifactId>
44+
<configuration>
45+
<rules>
46+
<banDuplicateClasses>
47+
<ignoreClasses combine.children="append">
48+
<ignoreClass>some.other.Class</ignoreClass>
49+
</ignoreClasses>
50+
<dependencies combine.children="append">
51+
<dependency>
52+
<groupId>org.slf4j</groupId>
53+
<artifactId>jcl-over-slf4j</artifactId>
54+
<ignoreClasses>
55+
<ignoreClass>org.slf4j.*</ignoreClass>
56+
</ignoreClasses>
57+
</dependency>
58+
</dependencies>
59+
</banDuplicateClasses>
60+
</rules>
61+
</configuration>
62+
</plugin>
63+
```
64+
65+
### Result
66+
67+
The child POM's effective configuration will include entries from both parent and child:
68+
69+
**ignoreClasses:**
70+
- `org.apache.commons.logging.*` (from parent)
71+
- `some.other.Class` (from child)
72+
73+
**dependencies:**
74+
- commons-logging configuration (from parent)
75+
- jcl-over-slf4j configuration (from child)
76+
77+
## Maven Configuration Combination
78+
79+
The `combine.children="append"` attribute is a standard Maven feature for controlling how configurations are merged during POM inheritance.
80+
81+
**Important Notes:**
82+
- The attribute must be placed on the collection element in the **child** POM (not the parent)
83+
- Works for both `<ignoreClasses>` and `<dependencies>` elements
84+
- Without this attribute, child configuration will **replace** parent configuration
85+
86+
See [Maven POM Reference](https://maven.apache.org/pom.html#Plugins) for more details on configuration combination.
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
3+
<modelVersion>4.0.0</modelVersion>
4+
5+
<parent>
6+
<groupId>org.codehaus.mojo.extra-enforcer-rules.it</groupId>
7+
<artifactId>banduplicate-classes-inheritance-parent</artifactId>
8+
<version>1.0-SNAPSHOT</version>
9+
</parent>
10+
11+
<artifactId>banduplicate-classes-inheritance-child</artifactId>
12+
<name>Test banDuplicateClasses inheritance - Child</name>
13+
14+
<build>
15+
<plugins>
16+
<plugin>
17+
<artifactId>maven-enforcer-plugin</artifactId>
18+
<configuration>
19+
<rules>
20+
<banDuplicateClasses>
21+
<ignoreClasses combine.children="append">
22+
<ignoreClass>some.other.Class</ignoreClass>
23+
</ignoreClasses>
24+
<dependencies combine.children="append">
25+
<dependency>
26+
<groupId>org.slf4j</groupId>
27+
<artifactId>jcl-over-slf4j</artifactId>
28+
<ignoreClasses>
29+
<ignoreClass>org.slf4j.*</ignoreClass>
30+
</ignoreClasses>
31+
</dependency>
32+
</dependencies>
33+
</banDuplicateClasses>
34+
</rules>
35+
</configuration>
36+
</plugin>
37+
</plugins>
38+
</build>
39+
40+
</project>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
invoker.goals = enforcer:enforce
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
3+
<modelVersion>4.0.0</modelVersion>
4+
5+
<groupId>org.codehaus.mojo.extra-enforcer-rules.it</groupId>
6+
<artifactId>banduplicate-classes-inheritance-parent</artifactId>
7+
<version>1.0-SNAPSHOT</version>
8+
<packaging>pom</packaging>
9+
<name>Test banDuplicateClasses inheritance - Parent</name>
10+
11+
<modules>
12+
<module>child</module>
13+
</modules>
14+
15+
<dependencies>
16+
<dependency>
17+
<groupId>commons-logging</groupId>
18+
<artifactId>commons-logging</artifactId>
19+
<version>1.1.1</version>
20+
</dependency>
21+
<dependency>
22+
<groupId>org.slf4j</groupId>
23+
<artifactId>jcl-over-slf4j</artifactId>
24+
<version>1.6.1</version>
25+
</dependency>
26+
</dependencies>
27+
28+
<build>
29+
<plugins>
30+
<plugin>
31+
<artifactId>maven-enforcer-plugin</artifactId>
32+
<version>@enforcerPluginVersion@</version>
33+
<dependencies>
34+
<dependency>
35+
<groupId>@project.groupId@</groupId>
36+
<artifactId>@project.artifactId@</artifactId>
37+
<version>@project.version@</version>
38+
</dependency>
39+
</dependencies>
40+
<configuration>
41+
<rules>
42+
<banDuplicateClasses>
43+
<ignoreClasses>
44+
<ignoreClass>org.apache.commons.logging.*</ignoreClass>
45+
</ignoreClasses>
46+
<dependencies>
47+
<dependency>
48+
<groupId>commons-logging</groupId>
49+
<artifactId>commons-logging</artifactId>
50+
<ignoreClasses>
51+
<ignoreClass>org.apache.commons.logging.impl.WeakHashtable*</ignoreClass>
52+
</ignoreClasses>
53+
</dependency>
54+
</dependencies>
55+
</banDuplicateClasses>
56+
</rules>
57+
</configuration>
58+
</plugin>
59+
</plugins>
60+
</build>
61+
62+
</project>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Verify that the build succeeded
2+
File buildLog = new File(basedir, "build.log")
3+
assert buildLog.exists()
4+
5+
String log = buildLog.text
6+
7+
// The build should succeed
8+
assert !log.contains("BUILD FAILURE"), "Build should have succeeded"
9+
10+
// Verify that the child's configuration includes both parent and child ignoreClasses
11+
// Look for the child module's configuration section
12+
def childConfig = log.find(/(?s)Building Test banDuplicateClasses inheritance - Child.*?end configuration/)
13+
assert childConfig != null, "Could not find child configuration in build log"
14+
15+
// Check that both ignore patterns are present in the child's effective configuration
16+
assert childConfig.contains("org.apache.commons.logging.*"), "Parent's ignoreClass pattern should be inherited"
17+
assert childConfig.contains("some.other.Class"), "Child's ignoreClass pattern should be present"
18+
19+
// Check that dependencies from both parent and child are present
20+
assert childConfig.contains("commons-logging"), "Parent's dependency configuration should be inherited"
21+
assert childConfig.contains("jcl-over-slf4j"), "Child's dependency configuration should be present"
22+
23+
println "Test passed: banDuplicateClasses correctly combined configuration from parent and child POMs"
24+
println " - Parent's ignoreClass pattern 'org.apache.commons.logging.*' was inherited"
25+
println " - Child's ignoreClass pattern 'some.other.Class' was added"
26+
println " - Parent's dependency configuration for 'commons-logging' was inherited"
27+
println " - Child's dependency configuration for 'jcl-over-slf4j' was added"

src/site/apt/banDuplicateClasses.apt.vm

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,69 @@ Ban Duplicate Classes
136136
+---+
137137

138138

139+
* Inheriting Configuration from Parent POMs
140+
141+
When you want to extend <<<banDuplicateClasses>>> configuration from a parent POM in a child POM, you must use Maven's <<<combine.children="append">>> attribute on the collection elements (<<<ignoreClasses>>> and <<<dependencies>>>) to append to the parent's configuration rather than replacing it.
142+
143+
Without this attribute, Maven will replace the parent's configuration entirely.
144+
145+
** Parent POM Example
146+
147+
+---+
148+
<plugin>
149+
<artifactId>maven-enforcer-plugin</artifactId>
150+
<configuration>
151+
<rules>
152+
<banDuplicateClasses>
153+
<ignoreClasses>
154+
<ignoreClass>org.apache.commons.logging.*</ignoreClass>
155+
</ignoreClasses>
156+
<dependencies>
157+
<dependency>
158+
<groupId>commons-logging</groupId>
159+
<artifactId>commons-logging</artifactId>
160+
<ignoreClasses>
161+
<ignoreClass>org.apache.commons.logging.impl.WeakHashtable*</ignoreClass>
162+
</ignoreClasses>
163+
</dependency>
164+
</dependencies>
165+
</banDuplicateClasses>
166+
</rules>
167+
</configuration>
168+
</plugin>
169+
+---+
170+
171+
** Child POM Example
172+
173+
+---+
174+
<plugin>
175+
<artifactId>maven-enforcer-plugin</artifactId>
176+
<configuration>
177+
<rules>
178+
<banDuplicateClasses>
179+
<ignoreClasses combine.children="append">
180+
<ignoreClass>some.other.Class</ignoreClass>
181+
</ignoreClasses>
182+
<dependencies combine.children="append">
183+
<dependency>
184+
<groupId>org.slf4j</groupId>
185+
<artifactId>jcl-over-slf4j</artifactId>
186+
<ignoreClasses>
187+
<ignoreClass>org.slf4j.*</ignoreClass>
188+
</ignoreClasses>
189+
</dependency>
190+
</dependencies>
191+
</banDuplicateClasses>
192+
</rules>
193+
</configuration>
194+
</plugin>
195+
+---+
196+
197+
Note: The <<<combine.children="append">>> attribute must be placed on the collection element in the child POM (not the parent POM).
198+
199+
See {{{https://maven.apache.org/pom.html#Plugins}Maven POM Reference}} for more details on configuration combination.
200+
201+
139202
* Trademarks
140203

141204
Apache, Apache Maven, Maven and the Apache feather logo are trademarks of The Apache Software Foundation.

0 commit comments

Comments
 (0)