Skip to content

Conversation

gnodet
Copy link
Contributor

@gnodet gnodet commented Sep 8, 2025

This PR addresses issue #11009 where Maven would encounter a StackOverflowError when resolving parent POMs that form a cycle.

Problem

When Maven encounters a cyclic dependency in parent POM resolution (e.g., A -> B -> A), it would enter an infinite recursion loop, eventually causing a StackOverflowError. This made Maven crash ungracefully without providing useful feedback to the user.

Solution

The fix implements cycle detection in the DefaultModelBuilder by:

  1. Tracking visited parents: Maintains a set of visited parent coordinates during resolution
  2. Cycle detection: When a parent that has already been visited is encountered again, it indicates a cycle
  3. Graceful error handling: Throws a ModelBuildingException with a clear error message instead of crashing

Changes Made

  • Modified DefaultModelBuilder: Added cycle detection logic in parent POM resolution methods
  • Added integration test: Comprehensive test case that verifies the fix works correctly
  • Test resources: Created test POMs with cyclic parent dependencies

Testing

The fix includes a comprehensive integration test (MavenITmng11009StackOverflowParentResolutionTest) that:

  • Creates a scenario with cyclic parent dependencies (A -> B -> A)
  • Verifies that StackOverflowError no longer occurs
  • Confirms that an appropriate cycle detection error is thrown
  • Ensures Maven fails gracefully with a meaningful error message

Backward Compatibility

This change is backward compatible as it only affects error handling for invalid POM structures. Valid POMs continue to work as before, while invalid cyclic structures now fail gracefully instead of crashing.

Related Issues

This commit addresses issue MNG-11009 where Maven would encounter a
StackOverflowError when resolving parent POMs that form a cycle.

Changes made:
- Modified DefaultModelBuilder to detect cycles in parent POM resolution
- Added cycle detection logic that tracks visited parent coordinates
- When a cycle is detected, throws ModelBuildingException with clear error message
- Added comprehensive integration test to verify the fix works correctly

The fix prevents infinite recursion by maintaining a set of visited parent
coordinates during the resolution process. When a parent that has already
been visited is encountered again, it indicates a cycle and the process
is terminated with an appropriate error message.

Integration test includes:
- Test case with cyclic parent dependencies (A -> B -> A)
- Verification that StackOverflowError no longer occurs
- Confirmation that appropriate cycle detection error is thrown
@gnodet gnodet changed the title Fix MNG-11009: Prevent StackOverflowError in parent POM resolution Fix #11009: Prevent StackOverflowError in parent POM resolution Sep 9, 2025
The original cycle detection implementation was incorrectly applied at the wrong level,
causing normal parent hierarchies to be identified as cycles. This resulted in test
failures where getEffectiveModel() returned null.

Key changes:
- Moved cycle detection from readParentLocally/readAsParentModel to resolveParent method
- Use model IDs (groupId:artifactId:version) instead of file paths for cycle detection
- Apply cycle detection only during actual parent resolution, not for every model processed
- Ensure proper cleanup in finally block to remove parent ID from resolution chain

This fix allows normal parent hierarchies to work correctly while still detecting
actual cycles like the MNG-11009 scenario where a parent references itself through
relative path resolution.

Fixes failing tests:
- DefaultModelBuilderTest.testPropertiesAndProfiles
- RequestTraceTest.testTraces
- TestApiStandalone.testStandalone
This change adds cycle detection when resolving parent POMs to prevent
infinite loops that can occur when there are circular parent references.

Key changes:
- Added cycle detection logic in DefaultModelBuilder.readParentExternally()
- Maintains a stack of currently resolving parent GAVs to detect cycles
- Throws ModelBuilderException with clear error message when cycle detected
- Added comprehensive test coverage in ParentCycleDetectionTest

The implementation tracks parent resolution using a ThreadLocal stack to
handle concurrent builds safely. When a cycle is detected, it provides
a detailed error message showing the complete cycle path.

Fixes potential infinite loops and stack overflow errors when processing
POMs with circular parent dependencies.
…jects

The parent cycle detection was previously interfering with the multi-module
project test because it was being triggered when multiple modules had the
same parent. This change ensures that:

1. The cycle detection still works for actual parent cycles
2. It doesn't interfere with legitimate multi-module scenarios
3. The DefaultMavenTest.testThatErrorDuringProjectDependencyGraphCreationAreStored
   test now passes correctly

The key fix was ensuring that the cycle detection properly handles the
parent chain cleanup and doesn't create false positives when multiple
modules reference the same parent POM.

Also updated the ParentCycleDetectionTest to use proper Maven 4.1.0
namespaces in the test POMs.
@Pankraz76
Copy link
Contributor

kindly asking if this is a connection/config issue or something code-related, as it is reproducible on my system as well.

    - [FATAL] Non-resolvable parent POM: The following artifacts could not be resolved: test:b:pom:1.0 (absent): Could not transfer artifact test:b:pom:1.0 from/to central (https://repo.maven.apache.org/maven2): Cannot access https://repo.maven.apache.org/maven2 with type default using the available connector factories: BasicRepositoryConnectorFactory (remote repositories: central (https://repo.maven.apache.org/maven2, default, releases)) and parent could not be found in reactor @ line 7, column 5 ==> 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

StackOverflowError during project model building
2 participants