How to find unnecessary jars in a project

Learn how to find unnecessary jars in a project with practical examples, diagrams, and best practices. Covers java, maven, jar development techniques with visual explanations.

Identifying and Removing Unnecessary JARs in Java Projects

Hero image for How to find unnecessary jars in a project

Learn how to effectively find and eliminate redundant or unused JAR files in your Java and Maven projects to reduce build times, improve performance, and minimize security risks.

In Java development, especially with Maven-based projects, it's common for the project's dependency tree to grow over time. This can lead to an accumulation of JAR files that are either no longer used, are transitively included but not directly needed, or are duplicates. Unnecessary JARs inflate your project's size, increase build and deployment times, and can even introduce security vulnerabilities or class loading conflicts. This article will guide you through various methods to identify and remove these redundant dependencies.

Understanding Maven's Dependency Mechanism

Maven manages project dependencies through the pom.xml file. When you declare a direct dependency, Maven automatically pulls in its transitive dependencies. While this simplifies dependency management, it can also lead to an overgrown dependency graph. Understanding how Maven resolves and includes these JARs is the first step in identifying the unnecessary ones.

flowchart TD
    A[Declare Direct Dependency] --> B{Maven Resolves Transitive Dependencies}
    B --> C[Dependency Tree Created]
    C --> D{Unused/Redundant JARs Identified?}
    D -- Yes --> E[Remove/Exclude]
    D -- No --> F[Project Build]

Maven Dependency Resolution Flow

Using Maven Dependency Plugins

Maven provides powerful plugins to analyze and manage dependencies. The maven-dependency-plugin is your primary tool for this task. It offers several goals to help you visualize and clean up your project's dependencies.

mvn dependency:tree

Displaying the full dependency tree

The dependency:tree command outputs a hierarchical representation of all project dependencies, including transitive ones. This can be overwhelming for large projects, but it's crucial for understanding the full scope. Look for dependencies that appear multiple times or seem unrelated to your project's core functionality.

mvn dependency:analyze

Analyzing dependencies for unused or declared but unused JARs

The dependency:analyze goal is particularly useful. It categorizes dependencies into two main groups:

  1. Used undeclared dependencies: These are dependencies your code uses but are not explicitly declared in your pom.xml. They are typically pulled in transitively by other dependencies. While not strictly 'unnecessary', it's good practice to declare them directly if your code directly uses classes from them.
  2. Unused declared dependencies: These are dependencies explicitly declared in your pom.xml but whose classes are not directly used by your project's source code. These are prime candidates for removal.

Excluding Transitive Dependencies

Once you identify an unnecessary transitive dependency, you can exclude it from being pulled into your project. This is done within the <exclusions> tag of the direct dependency that brings it in.

<dependency>
    <groupId>com.example</groupId>
    <artifactId>parent-lib</artifactId>
    <version>1.0.0</version>
    <exclusions>
        <exclusion>
            <groupId>com.unnecessary</groupId>
            <artifactId>unnecessary-lib</artifactId>
        </exclusion>
    </exclusions>
</dependency>

Excluding a transitive dependency in pom.xml

Advanced Analysis with IDEs and External Tools

Modern IDEs like IntelliJ IDEA and Eclipse offer built-in dependency analysis tools that provide a more visual and interactive way to explore your project's dependencies. Additionally, external tools can offer deeper insights.

Hero image for How to find unnecessary jars in a project

Visualizing dependencies in an IDE (e.g., IntelliJ IDEA's Dependency Analyzer)

For instance, IntelliJ IDEA's 'Analyze Dependencies' feature (accessible via Maven -> Show Dependencies) provides a graphical representation of your dependency tree, making it easier to spot redundant or conflicting JARs. Similarly, tools like Tattletale or OWASP Dependency-Check can provide detailed reports on dependencies, including potential security vulnerabilities and duplicate classes.

1. Step 1: Run mvn dependency:tree

Execute this command to get a full overview of your project's dependency graph. Save the output to a file for easier review.

2. Step 2: Run mvn dependency:analyze

Identify 'unused declared dependencies' as primary candidates for removal. Also note 'used undeclared dependencies' for potential direct declaration.

3. Step 3: Review and Exclude

For each identified unnecessary JAR, determine if it can be safely removed or excluded. If it's a direct dependency, remove it from pom.xml. If it's transitive, add an <exclusion> to the direct parent dependency.

4. Step 4: Rebuild and Test

After making changes, always perform a clean build (mvn clean install) and run all your project's tests to ensure no functionality has been broken.

5. Step 5: Repeat and Refine

Dependency management is an ongoing process. Periodically review your dependencies, especially after major library upgrades or new feature development.