Skip to content

Strip internal module dependencies from ivy.xml before resolve to prevent stale transitive deps#184

Open
stijn-vranckx wants to merge 3 commits into
guymahieu:masterfrom
stijn-vranckx:master
Open

Strip internal module dependencies from ivy.xml before resolve to prevent stale transitive deps#184
stijn-vranckx wants to merge 3 commits into
guymahieu:masterfrom
stijn-vranckx:master

Conversation

@stijn-vranckx

Copy link
Copy Markdown

When IvyIDEA resolves Module A that depends on another workspace Module B, Ivy resolves the full dependency tree from the Ivy repository server. Even though IvyIDEA correctly replaces Module B with a module reference, the transitive dependencies resolved from the server's version of Module B (which may be outdated) are still added as external library entries.

Example: Module A depends on Module B. After updating Dependency X from v1 to v2 in Module B's ivy.xml, resolving Module A pulls in both v1 and v2 of Dependency X — v2 from the workspace module reference, and v1 resolved transitively from the server's outdated Module B descriptor.

Root cause: DependencyResolver.extractDependencies() processes the flattened resolve tree. Even when Module B is correctly detected as an internal module and replaced with a module reference, Module B's transitive dependencies from the server are separate entries in the resolved set and pass through as external dependencies.

Fix: Before resolving, identify internal module dependencies and remove them from the ivy descriptor passed to Ivy's resolve engine. This ensures the server is never consulted for workspace modules or their transitive closures. Internal module references are added back manually after resolve via InternalDependency.

Files changed:

  • DependencyResolver.java — Pre-filter internal deps from the ivy descriptor before resolve; fall back to original behavior on error; add InternalDependency entries after resolve
  • IntellijModuleDependencies.java — Expose hasInternalDependencies(), getInternalModuleIds(), getAllDependencyModules()

@codecov-commenter

codecov-commenter commented Jun 3, 2026

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 17.44186% with 71 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (master@60e6e62). Learn more about missing BASE report.

Files with missing lines Patch % Lines
...g/clarent/ivyidea/ivy/WorkspaceModuleResolver.java 21.53% 50 Missing and 1 partial ⚠️
...rg/clarent/ivyidea/config/IvyIdeaConfigHelper.java 0.00% 19 Missing ⚠️
src/main/java/org/clarent/ivyidea/ivy/IvyUtil.java 50.00% 1 Missing ⚠️
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.
Additional details and impacted files
@@           Coverage Diff            @@
##             master    #184   +/-   ##
========================================
  Coverage          ?   5.45%           
========================================
  Files             ?      59           
  Lines             ?    1393           
  Branches          ?     224           
========================================
  Hits              ?      76           
  Misses            ?    1311           
  Partials          ?       6           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@maartenc

maartenc commented Jun 3, 2026

Copy link
Copy Markdown
Collaborator

By removing the internal dependencies you might influence the resolve results, especially wrt conflict manangement.

Take your example:
Module A has a direct dependency on module B and a direct dependency on library X v1.
Module B has a direct dependency on library X v2.

If Ivy resolves the dependencies of module A, library X v1 will get evicted by v2.
If IvyIDEA would remove the 'moduleB' dependency from the ivy.xml of module A before resolving, Ivy will no longer evict library X v1.

I think the only correct solution here is to write some kind of 'project' resolver, which takes the modules of the project into account when resolving dependencies. Something similar as the (archived) IvyDE Eclipse workspace resolver: https://github.com/apache/ant-ivyde/blob/master/org.apache.ivyde.eclipse/src/java/org/apache/ivyde/internal/eclipse/workspaceresolver/WorkspaceResolver.java

@stijn-vranckx

Copy link
Copy Markdown
Author

Replace pre-filtering with workspace module resolver for inter-module dependencies

Instead of filtering internal module dependencies from ivy.xml before resolution (which breaks Ivy's conflict resolution), a custom Ivy resolver (WorkspaceModuleResolver) intercepts resolution requests for workspace modules and returns their local ivy.xml descriptors. This preserves transitive dependency management while keeping workspace module descriptors fresh.

Key changes:

  • WorkspaceModuleResolver: custom AbstractResolver that serves local ivy.xml descriptors for modules with the IvyIDEA facet in the same project
  • IvyIdeaConfigHelper.wrapResolverChain(): wraps ALL resolvers (not just default) in a ChainResolver with WorkspaceModuleResolver first, so module-specific resolver mappings still hit the workspace resolver
  • IvyUtil: added parseIvyFile(File, IvySettings) overload
  • Tests: WorkspaceModuleResolverTest with 9 tests verifying descriptor cloning

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.

3 participants