{"id":1911,"date":"2025-02-12T09:17:27","date_gmt":"2025-02-12T01:17:27","guid":{"rendered":"https:\/\/www.fanyamin.com\/wordpress\/?p=1911"},"modified":"2025-02-12T09:17:27","modified_gmt":"2025-02-12T01:17:27","slug":"solve-the-dependency-hell-by-maven","status":"publish","type":"post","link":"https:\/\/www.fanyamin.com\/wordpress\/?p=1911","title":{"rendered":"Solve the dependency hell by maven"},"content":{"rendered":"<p>Resolving version conflicts in Maven can be tricky, but Maven provides several strategies and mechanisms to handle dependency conflicts effectively. Here\u2019s a deeper dive into how you can resolve version conflicts in Maven:<\/p>\n<h3>1. <strong>Maven's Dependency Mediation (Nearest-Wins Strategy)<\/strong><\/h3>\n<p>Maven uses a <strong>nearest-wins<\/strong> strategy to resolve version conflicts. This means that when multiple versions of the same dependency are found in the dependency tree, Maven will pick the version that is <strong>closest<\/strong> to the project in terms of the dependency hierarchy.<\/p>\n<h4>Example:<\/h4>\n<p>Suppose you have two dependencies in your project:<\/p>\n<ul>\n<li><strong>Library A<\/strong> depends on version 1.0 of <code>libX<\/code>.<\/li>\n<li><strong>Library B<\/strong> depends on version 2.0 of <code>libX<\/code>.<\/li>\n<\/ul>\n<p>If both <code>Library A<\/code> and <code>Library B<\/code> are in the same project, Maven will pick <strong>libX version 2.0<\/strong> if it's the version that appears closest to your project in the dependency hierarchy.<\/p>\n<p>This is because Maven considers the <strong>direct dependencies<\/strong> first and chooses the one closer to your project.<\/p>\n<h4>How to Fix:<\/h4>\n<p>If you need to enforce a particular version, you can explicitly specify the version in your <strong>dependencyManagement<\/strong> section (see below) or override it using <strong>dependency exclusions<\/strong>.<\/p>\n<h3>2. <strong>Using <code>&lt;dependencyManagement&gt;<\/code> for Centralized Version Control<\/strong><\/h3>\n<p>Maven provides a <code>&lt;dependencyManagement&gt;<\/code> section, where you can specify versions for all your dependencies in one place. This allows you to ensure that all submodules or transitive dependencies use the same version of a dependency.<\/p>\n<h4>Example:<\/h4>\n<p>You have a multi-module project or you want to ensure consistency across different parts of your application.<\/p>\n<pre><code class=\"language-xml\">&lt;dependencyManagement&gt;\n    &lt;dependencies&gt;\n        &lt;!-- Define the version of libX --&gt;\n        &lt;dependency&gt;\n            &lt;groupId&gt;com.example&lt;\/groupId&gt;\n            &lt;artifactId&gt;libX&lt;\/artifactId&gt;\n            &lt;version&gt;2.0&lt;\/version&gt;\n        &lt;\/dependency&gt;\n    &lt;\/dependencies&gt;\n&lt;\/dependencyManagement&gt;<\/code><\/pre>\n<p>This ensures that <strong>libX<\/strong> version 2.0 is used consistently across the entire project, even if other libraries bring in different versions of <code>libX<\/code> as transitive dependencies.<\/p>\n<h3>3. <strong>Excluding Transitive Dependencies<\/strong><\/h3>\n<p>Sometimes, dependencies you include may bring in conflicting versions of libraries you don't need. In such cases, you can <strong>exclude<\/strong> those transitive dependencies from being included in your project.<\/p>\n<h4>Example:<\/h4>\n<p>Suppose <strong>Library A<\/strong> depends on <code>libX<\/code> version 1.0, but you want to use version 2.0. You can exclude version 1.0 from <code>Library A<\/code>.<\/p>\n<pre><code class=\"language-xml\">&lt;dependency&gt;\n    &lt;groupId&gt;com.example&lt;\/groupId&gt;\n    &lt;artifactId&gt;libraryA&lt;\/artifactId&gt;\n    &lt;version&gt;1.0&lt;\/version&gt;\n    &lt;exclusions&gt;\n        &lt;exclusion&gt;\n            &lt;groupId&gt;com.example&lt;\/groupId&gt;\n            &lt;artifactId&gt;libX&lt;\/artifactId&gt;\n        &lt;\/exclusion&gt;\n    &lt;\/exclusions&gt;\n&lt;\/dependency&gt;<\/code><\/pre>\n<p>This tells Maven not to include <code>libX<\/code> version 1.0 from <strong>Library A<\/strong>.<\/p>\n<h3>4. <strong>Using <code>mvn dependency:tree<\/code> to Investigate Dependencies<\/strong><\/h3>\n<p>Maven provides the <code>dependency:tree<\/code> command to show a hierarchical view of all dependencies, including their transitive dependencies. This is very useful for identifying version conflicts.<\/p>\n<pre><code class=\"language-bash\">mvn dependency:tree<\/code><\/pre>\n<p>This will display the entire dependency tree, showing which versions of libraries are being pulled in and where conflicts might exist.<\/p>\n<h4>Example Output:<\/h4>\n<pre><code>[INFO] com.example:project:jar:1.0\n[INFO] +- com.example:libraryA:jar:1.0:compile\n[INFO] |  \\- com.example:libX:jar:1.0:compile\n[INFO] +- com.example:libraryB:jar:1.0:compile\n[INFO] |  \\- com.example:libX:jar:2.0:compile\n[INFO] \\- com.example:libraryC:jar:1.0:compile\n[INFO]    \\- com.example:libX:jar:2.0:compile<\/code><\/pre>\n<p>In this case, you can see that <code>libX<\/code> version 1.0 is pulled in by <code>libraryA<\/code>, and version 2.0 is pulled in by <code>libraryB<\/code> and <code>libraryC<\/code>. This can help you determine which dependency is causing the conflict.<\/p>\n<h3>5. <strong>Using <code>exclusions<\/code> and <code>dependencyManagement<\/code> Together<\/strong><\/h3>\n<p>In some cases, you may want to both exclude conflicting versions and explicitly define the version you want. For instance:<\/p>\n<pre><code class=\"language-xml\">&lt;dependency&gt;\n    &lt;groupId&gt;com.example&lt;\/groupId&gt;\n    &lt;artifactId&gt;libraryA&lt;\/artifactId&gt;\n    &lt;version&gt;1.0&lt;\/version&gt;\n    &lt;exclusions&gt;\n        &lt;exclusion&gt;\n            &lt;groupId&gt;com.example&lt;\/groupId&gt;\n            &lt;artifactId&gt;libX&lt;\/artifactId&gt;\n        &lt;\/exclusion&gt;\n    &lt;\/exclusions&gt;\n&lt;\/dependency&gt;\n\n&lt;dependencyManagement&gt;\n    &lt;dependencies&gt;\n        &lt;!-- Enforce version of libX --&gt;\n        &lt;dependency&gt;\n            &lt;groupId&gt;com.example&lt;\/groupId&gt;\n            &lt;artifactId&gt;libX&lt;\/artifactId&gt;\n            &lt;version&gt;2.0&lt;\/version&gt;\n        &lt;\/dependency&gt;\n    &lt;\/dependencies&gt;\n&lt;\/dependencyManagement&gt;<\/code><\/pre>\n<p>This ensures that you only get the version 2.0 of <code>libX<\/code>, regardless of what versions are pulled in by other libraries.<\/p>\n<h3>6. <strong>Enforcing Version With <code>dependencyVersion<\/code> Plugin<\/strong><\/h3>\n<p>If you want to enforce specific versions across your project, you can use the <code>versions-maven-plugin<\/code> to report and enforce dependency versions.<\/p>\n<h4>Example of Enforcing Versions:<\/h4>\n<pre><code class=\"language-bash\">mvn versions:use-latest-versions<\/code><\/pre>\n<p>This command will automatically update your dependencies to the latest versions according to your project's current configuration.<\/p>\n<h3>7. <strong>Use BOM (Bill of Materials)<\/strong><\/h3>\n<p>In larger projects or when managing dependencies across multiple modules, you can use a <strong>BOM<\/strong> to centralize the versions of dependencies. BOMs can be used to ensure that all modules use the same version of a dependency.<\/p>\n<h4>Example:<\/h4>\n<pre><code class=\"language-xml\">&lt;dependencyManagement&gt;\n    &lt;dependencies&gt;\n        &lt;dependency&gt;\n            &lt;groupId&gt;com.example&lt;\/groupId&gt;\n            &lt;artifactId&gt;libX&lt;\/artifactId&gt;\n            &lt;version&gt;2.0&lt;\/version&gt;\n        &lt;\/dependency&gt;\n    &lt;\/dependencies&gt;\n&lt;\/dependencyManagement&gt;<\/code><\/pre>\n<p>If you're using a third-party BOM, you can import it into your <code>pom.xml<\/code> as follows:<\/p>\n<pre><code class=\"language-xml\">&lt;dependencyManagement&gt;\n    &lt;dependencies&gt;\n        &lt;dependency&gt;\n            &lt;groupId&gt;org.springframework&lt;\/groupId&gt;\n            &lt;artifactId&gt;spring-framework-bom&lt;\/artifactId&gt;\n            &lt;version&gt;5.3.10&lt;\/version&gt;\n            &lt;scope&gt;import&lt;\/scope&gt;\n            &lt;type&gt;pom&lt;\/type&gt;\n        &lt;\/dependency&gt;\n    &lt;\/dependencies&gt;\n&lt;\/dependencyManagement&gt;<\/code><\/pre>\n<p>This ensures that all Spring-related dependencies are consistent across all modules of your project.<\/p>\n<hr \/>\n<h3>Summary<\/h3>\n<p>To resolve version conflicts in Maven, you can:<\/p>\n<ul>\n<li>Use <strong>dependencyManagement<\/strong> to centralize dependency versions and avoid discrepancies across modules.<\/li>\n<li><strong>Exclude transitive dependencies<\/strong> when unnecessary or conflicting.<\/li>\n<li>Investigate dependency issues using the <code>mvn dependency:tree<\/code> command.<\/li>\n<li>Enforce specific versions using plugins like <code>versions-maven-plugin<\/code> and BOMs (Bill of Materials).<\/li>\n<li>Rely on Maven\u2019s <strong>nearest-wins<\/strong> strategy carefully, ensuring that the correct version of a library is used.<\/li>\n<\/ul>\n<p>By applying these practices, you can ensure better version control and avoid issues related to dependency conflicts in your Maven project.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Resolving version conflicts in Maven can be tricky, but Maven provides several strategies and mechanisms to handle dependency conflicts effectively. Here\u2019s a deeper dive into how you can resolve version conflicts in Maven: 1. Maven&#8217;s Dependency Mediation (Nearest-Wins Strategy) Maven uses a nearest-wins strategy to resolve version conflicts. This means that when multiple versions of [&hellip;] <a class=\"read-more\" href=\"https:\/\/www.fanyamin.com\/wordpress\/?p=1911\" title=\"Permanent Link to: Solve the dependency hell by maven\">&rarr;Read&nbsp;more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[],"class_list":["post-1911","post","type-post","status-publish","format-standard","hentry","category-5"],"_links":{"self":[{"href":"https:\/\/www.fanyamin.com\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/1911"}],"collection":[{"href":"https:\/\/www.fanyamin.com\/wordpress\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.fanyamin.com\/wordpress\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.fanyamin.com\/wordpress\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.fanyamin.com\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1911"}],"version-history":[{"count":1,"href":"https:\/\/www.fanyamin.com\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/1911\/revisions"}],"predecessor-version":[{"id":1912,"href":"https:\/\/www.fanyamin.com\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/1911\/revisions\/1912"}],"wp:attachment":[{"href":"https:\/\/www.fanyamin.com\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1911"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.fanyamin.com\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1911"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.fanyamin.com\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1911"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}