← Back to Advanced Java Course | Chapter 12: Build Tools | Lesson 4 of 5

Java Dependency Management

Dependency management covers declaring direct dependencies, understanding the transitive ones they pull in, controlling their scope, and resolving version conflicts between competing requirements.

What is a Dependency?

A dependency is an external library a project needs to compile or run, declared in the build file with coordinates identifying exactly which library and version to download from a repository like Maven Central.

Example: What is a Dependency?

java
public class Main {
	public static void main(String[] args) {
		String coordinates = "com.google.guava:guava:32.1.0"; // groupId:artifactId:version
		System.out.println(coordinates);
	}
}

Direct vs Transitive Dependencies

A direct dependency is one explicitly listed in the build file, while a transitive dependency is one pulled in automatically because a direct dependency itself depends on it, often resulting in far more libraries on the classpath than were ever directly declared.

Example: Direct vs Transitive Dependencies

java
public class Main {
	public static void main(String[] args) {
		String direct = "junit:junit:4.13"; // explicitly listed
		String transitive = "hamcrest-core"; // pulled in automatically because junit depends on it
		System.out.println(direct + " brings in " + transitive);
	}
}

Dependency Scopes

Dependency scopes control when and where a dependency is available -- compile scope is available everywhere, test scope only during testing, and provided scope assumes the runtime environment already supplies the library.

Example: Dependency Scopes

java
public class Main {
	public static void main(String[] args) {
		String compileScope = "compile"; // available everywhere
		String testScope = "test"; // only during testing
		String providedScope = "provided"; // runtime environment already supplies it
		System.out.println(compileScope + " " + testScope + " " + providedScope);
	}
}

Resolving Version Conflicts

Version conflicts happen when two dependencies transitively require different versions of the same library, and build tools resolve this automatically using rules like nearest-wins, though dependencyManagement can pin an exact version explicitly.

Example: Resolving Version Conflicts

java
public class Main {
	public static void main(String[] args) {
		String pinned = "<dependencyManagement>...<version>2.0</version></dependencyManagement>"; // pins the exact version
		System.out.println(pinned);
	}
}

Excluding Dependencies

A transitive dependency can sometimes be undesirable, such as an unwanted embedded server or a conflicting logging library, and both Maven and Gradle support explicitly excluding specific transitive dependencies from a declared dependency.

Example: Excluding Dependencies

java
// Define the class Main
public class Main {
	// Program entry point: the JVM starts running here
	public static void main(String[] args) {
		String exclusion = "<exclusions><exclusion><artifactId>unwanted-logger</artifactId></exclusion></exclusions>";
		// Print a line to the console
		System.out.println(exclusion);
	}
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Relying on a transitive dependency without declaring it, so the build breaks when the library that brought it stops including it.
  2. Declaring a test library in compile scope, or a library needed at runtime in test scope, so it is missing or bundled where it should not be.
  3. Ignoring version conflicts between libraries, when you should inspect them with mvn dependency:tree and pick or exclude versions on purpose.
🔒

Chapter Quiz — Complete all 5 topics to unlock

0/5 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.