@@ -1061,10 +1061,6 @@ private File shadedTestArtifactFile()
1061
1061
private void createDependencyReducedPom ( Set <String > artifactsToRemove )
1062
1062
throws IOException , DependencyGraphBuilderException , ProjectBuildingException
1063
1063
{
1064
- List <Dependency > dependencies = new ArrayList <>();
1065
-
1066
- boolean modified = false ;
1067
-
1068
1064
List <Dependency > transitiveDeps = new ArrayList <>();
1069
1065
1070
1066
// NOTE: By using the getArtifacts() we get the completely evaluated artifacts
@@ -1083,39 +1079,48 @@ private void createDependencyReducedPom( Set<String> artifactsToRemove )
1083
1079
// we'll figure out the exclusions in a bit.
1084
1080
transitiveDeps .add ( dep );
1085
1081
}
1086
- List <Dependency > origDeps = project .getDependencies ();
1087
1082
1088
- if ( promoteTransitiveDependencies )
1083
+ Model model = project .getOriginalModel ();
1084
+
1085
+ // MSHADE-413: Must not use objects (for example `Model` or `Dependency`) that are "owned
1086
+ // by Maven" and being used by other projects/plugins. Modifying those will break the
1087
+ // correctness of the build - or cause an endless loop.
1088
+ List <Dependency > origDeps = new ArrayList <>();
1089
+ List <Dependency > source = promoteTransitiveDependencies ? transitiveDeps : project .getDependencies ();
1090
+ for ( Dependency d : source )
1089
1091
{
1090
- origDeps = transitiveDeps ;
1092
+ origDeps . add ( d . clone () ) ;
1091
1093
}
1094
+ model = model .clone ();
1092
1095
1093
- Model model = project .getOriginalModel ();
1094
1096
// MSHADE-185: We will remove all system scoped dependencies which usually
1095
1097
// have some kind of property usage. At this time the properties within
1096
1098
// such things are already evaluated.
1097
1099
List <Dependency > originalDependencies = model .getDependencies ();
1098
1100
removeSystemScopedDependencies ( artifactsToRemove , originalDependencies );
1099
1101
1102
+ List <Dependency > dependencies = new ArrayList <>();
1103
+ boolean modified = false ;
1100
1104
for ( Dependency d : origDeps )
1101
1105
{
1102
- dependencies .add ( d );
1103
-
1104
- String id = getId ( d );
1105
-
1106
- if ( artifactsToRemove .contains ( id ) )
1106
+ if ( artifactsToRemove .contains ( getId ( d ) ) )
1107
1107
{
1108
- modified = true ;
1109
-
1110
1108
if ( keepDependenciesWithProvidedScope )
1111
1109
{
1112
- d .setScope ( "provided" );
1110
+ if ( !"provided" .equals ( d .getScope () ) )
1111
+ {
1112
+ modified = true ;
1113
+ d .setScope ( "provided" );
1114
+ }
1113
1115
}
1114
1116
else
1115
1117
{
1116
- dependencies .remove ( d );
1118
+ modified = true ;
1119
+ continue ;
1117
1120
}
1118
1121
}
1122
+
1123
+ dependencies .add ( d );
1119
1124
}
1120
1125
1121
1126
// MSHADE-155
@@ -1299,8 +1304,13 @@ public boolean updateExcludesInDeps( MavenProject project, List<Dependency> depe
1299
1304
boolean modified = false ;
1300
1305
for ( DependencyNode n2 : node .getChildren () )
1301
1306
{
1307
+ String artifactId2 = getId ( n2 .getArtifact () );
1308
+
1302
1309
for ( DependencyNode n3 : n2 .getChildren () )
1303
1310
{
1311
+ Artifact artifact3 = n3 .getArtifact ();
1312
+ String artifactId3 = getId ( artifact3 );
1313
+
1304
1314
// check if it really isn't in the list of original dependencies. Maven
1305
1315
// prior to 2.0.8 may grab versions from transients instead of
1306
1316
// from the direct deps in which case they would be marked included
@@ -1310,7 +1320,7 @@ public boolean updateExcludesInDeps( MavenProject project, List<Dependency> depe
1310
1320
boolean found = false ;
1311
1321
for ( Dependency dep : transitiveDeps )
1312
1322
{
1313
- if ( getId ( dep ).equals ( getId ( n3 . getArtifact () ) ) )
1323
+ if ( getId ( dep ).equals ( artifactId3 ) )
1314
1324
{
1315
1325
found = true ;
1316
1326
break ;
@@ -1321,18 +1331,31 @@ public boolean updateExcludesInDeps( MavenProject project, List<Dependency> depe
1321
1331
// note: MSHADE-31 introduced the exclusion logic for promoteTransitiveDependencies=true,
1322
1332
// but as of 3.2.1 promoteTransitiveDependencies has no effect for provided deps,
1323
1333
// which makes this fix even possible (see also MSHADE-181)
1324
- if ( !found && !"provided" .equals ( n3 . getArtifact () .getScope () ) )
1334
+ if ( !found && !"provided" .equals ( artifact3 .getScope () ) )
1325
1335
{
1336
+ getLog ().debug ( String .format ( "dependency %s (scope %s) not found in transitive dependencies" ,
1337
+ artifactId3 , artifact3 .getScope () ) );
1326
1338
for ( Dependency dep : dependencies )
1327
1339
{
1328
- if ( getId ( dep ).equals ( getId ( n2 . getArtifact () ) ) )
1340
+ if ( getId ( dep ).equals ( artifactId2 ) )
1329
1341
{
1330
- Exclusion exclusion = new Exclusion ();
1331
- exclusion .setArtifactId ( n3 .getArtifact ().getArtifactId () );
1332
- exclusion .setGroupId ( n3 .getArtifact ().getGroupId () );
1333
- dep .addExclusion ( exclusion );
1334
- modified = true ;
1335
- break ;
1342
+ // MSHADE-413: First check whether the exclusion has already been added,
1343
+ // because it's meaningless to add it more than once. Certain cases
1344
+ // can end up adding the exclusion "forever" and cause an endless loop
1345
+ // rewriting the whole dependency-reduced-pom.xml file.
1346
+ if ( !dependencyHasExclusion ( dep , artifact3 ) )
1347
+ {
1348
+ getLog ().debug ( String .format ( "Adding exclusion for dependency %s (scope %s) "
1349
+ + "to %s (scope %s)" ,
1350
+ artifactId3 , artifact3 .getScope (),
1351
+ getId ( dep ), dep .getScope () ) );
1352
+ Exclusion exclusion = new Exclusion ();
1353
+ exclusion .setArtifactId ( artifact3 .getArtifactId () );
1354
+ exclusion .setGroupId ( artifact3 .getGroupId () );
1355
+ dep .addExclusion ( exclusion );
1356
+ modified = true ;
1357
+ break ;
1358
+ }
1336
1359
}
1337
1360
}
1338
1361
}
@@ -1347,6 +1370,21 @@ public boolean updateExcludesInDeps( MavenProject project, List<Dependency> depe
1347
1370
}
1348
1371
}
1349
1372
1373
+ private boolean dependencyHasExclusion ( Dependency dep , Artifact exclusionToCheck )
1374
+ {
1375
+ boolean containsExclusion = false ;
1376
+ for ( Exclusion existingExclusion : dep .getExclusions () )
1377
+ {
1378
+ if ( existingExclusion .getGroupId ().equals ( exclusionToCheck .getGroupId () )
1379
+ && existingExclusion .getArtifactId ().equals ( exclusionToCheck .getArtifactId () ) )
1380
+ {
1381
+ containsExclusion = true ;
1382
+ break ;
1383
+ }
1384
+ }
1385
+ return containsExclusion ;
1386
+ }
1387
+
1350
1388
private List <ResourceTransformer > toResourceTransformers (
1351
1389
String shade , List <ResourceTransformer > resourceTransformers )
1352
1390
{
0 commit comments