Question

Add External JAR Files to an IntelliJ IDEA Java Project

javaintellij-ideabuilddependency-management

Question

When I create a new Java project in IntelliJ IDEA, it contains files and directories similar to the following:

projectname.iml
projectname.ipr
projectname.iws
src/

I have dependency JAR files in a lib/ directory, such as lib/*.jar. What is the correct way to configure IntelliJ IDEA so those JAR files are available to my project during compilation and execution?

Short Answer

You will learn how Java JAR dependencies are added to an IntelliJ IDEA module, why adding a file to the project folder is not enough, and why Maven or Gradle is usually the better long-term dependency-management approach.

Concept

A JAR (Java Archive) is a file that can contain compiled Java classes, resources, and metadata. When your code imports a class from an external JAR, Java must be able to find that JAR on the project's classpath.

In IntelliJ IDEA, dependencies are normally configured per module. Adding JAR files to the project directory, such as lib/, makes them visible in the Project tool window, but it does not automatically put them on the classpath.

To use local JARs, add them as a module library:

  1. Open File → Project Structure.
  2. Select Modules.
  3. Select the module that contains your Java source code.
  4. Open the Dependencies tab.
  5. Click + and choose JARs or Directories.
  6. Select one or more JAR files in lib/.
  7. Choose the appropriate dependency scope, usually Compile.
  8. Apply the changes.

Afterward, IntelliJ IDEA can resolve imports from those JARs, compile against them, and include them on the runtime classpath when you run the application.

For projects with dependencies that may change, use a build tool such as Maven or Gradle instead of manually adding JAR files. A build tool records dependency versions in a text file and can download, update, and share dependencies consistently.

Mental Model

Think of your project as a workshop and the Java compiler as a worker.

  • Your src/ directory is the workshop's set of instructions.
  • A JAR file is a toolbox containing reusable parts.
  • The classpath is the shelf list that tells the worker where each toolbox is stored.

Putting a toolbox in the building (lib/) does not tell the worker to use it. Adding the JAR as a module dependency adds it to the shelf list, so the compiler and application can find its classes.

Take Quiz

Syntax and Examples

A local-JAR project is often organized like this:

my-app/
├── lib/
│   └── example-library.jar
└── src/
    └── Main.java

After adding example-library.jar in Project Structure → Modules → Dependencies, Java code can import classes that the JAR provides:

import com.example.library.Greeter;

public class Main {
    public static void main(String[] args) {
        Greeter greeter = new Greeter();
        System.out.println(greeter.greet("Ada"));
    }
}

The exact package and class names depend on the JAR you use. If the dependency was added correctly, IntelliJ IDEA will not mark Greeter as unresolved.

Dependency scopes

When adding a JAR, IntelliJ IDEA asks for a scope. The most common choices are:

  • Compile: needed to compile and run the main application. This is the usual choice for application libraries.
  • Test: needed only by test code, such as a testing library.
  • Runtime: needed when running but not when compiling, which is less common for beginners.
  • Provided: expected to be supplied by the deployment environment, such as some server APIs.

Choose Compile unless you specifically know the JAR belongs only to tests or is supplied externally.

Step by Step Execution

Consider this code after a JAR containing com.example.library.Greeter has been added as a Compile dependency:

import com.example.library.Greeter;

public class Main {
    public static void main(String[] args) {
        Greeter greeter = new Greeter();
        String message = greeter.greet("Sam");
        System.out.println(message);
    }
}

What happens:

  1. IntelliJ IDEA reads the module's dependency list.
  2. It finds the configured JAR and indexes the classes inside it.
  3. The import statement is resolved to Greeter in that JAR.
  4. During compilation, javac receives the JAR as part of its classpath.
  5. new Greeter() creates an object from the external library.
  6. greeter.greet("Sam") calls code packaged in the JAR.
  7. When the run configuration starts, IntelliJ IDEA also includes the JAR on the runtime classpath.

If the JAR is missing from the runtime classpath, compilation may succeed in some setups but execution can fail with an error such as NoClassDefFoundError. Configuring it as a normal module dependency prevents that mismatch.

Real World Use Cases

Local JAR dependencies are useful in several situations:

  • Company-internal libraries: A team may provide a shared JAR that is not published to a public repository.
  • Legacy applications: Older Java projects often keep third-party libraries in a checked-in lib/ folder.
  • Offline or restricted environments: A project may need to build without downloading packages from the internet.
  • Vendor SDKs: Hardware, payment, reporting, or enterprise vendors sometimes distribute their Java SDK as JAR files.
  • Small prototypes: Adding one local JAR can be quick for a short experiment.

For an application that uses many libraries or is maintained by multiple developers, Maven or Gradle is usually easier and safer.

Take Quiz

Real Codebase Usage

In maintained Java codebases, developers generally avoid relying only on IDE configuration. IntelliJ IDEA project metadata is specific to the IDE, while a build file can be used by IntelliJ IDEA, command-line builds, CI servers, and other developers.

Prefer Maven or Gradle for published dependencies

A Maven dependency is declared in pom.xml:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.14.0</version>
</dependency>

A Gradle dependency is declared in build.gradle:

dependencies {
    implementation 'org.apache.commons:commons-lang3:3.14.0'
}

IntelliJ IDEA imports these declarations and configures the module classpath automatically.

Use a repository for internal JARs when possible

Teams often publish internal libraries to a private Maven repository instead of copying JARs into each project. This gives the dependency a name and version, supports repeatable builds, and makes upgrades explicit.

If a local JAR is required

Keep it in a predictable location such as lib/, document its source and version, and ensure the build system also knows about it. For example, a Gradle project can refer to a local JAR:

dependencies {
    implementation files('lib/example-library.jar')
}

The important rule is that the project should build outside IntelliJ IDEA as well as inside it.

Common Mistakes

Assuming lib/ is automatically a dependency folder

This does not configure a classpath:

my-app/
├── lib/
│   └── example-library.jar
└── src/
    └── Main.java

Avoid it: Add the JAR through Project Structure → Modules → Dependencies, or declare it in Maven or Gradle.

Adding the JAR to the wrong module

A project can contain multiple modules. Adding a JAR to one module does not automatically make it available to another module.

Avoid it: Select the module that contains the code with the unresolved import, then add the dependency on that module's Dependencies tab.

Choosing the wrong scope

A library used by main code should not normally be marked as Test. Main source code will then fail to compile because test dependencies are not available there.

Avoid it: Use Compile for application libraries and Test only for dependencies used exclusively by tests.

Adding a JAR as a source folder

A JAR is a compiled dependency, not a Java source root.

Avoid it: Use JARs or Directories in the module dependency settings rather than marking lib/ as a source directory.

Committing only IntelliJ IDEA configuration

If only your .iml file contains dependency information, a teammate or CI system may not reproduce the build reliably.

Avoid it: Prefer a pom.xml or build.gradle file. If local JARs must be committed, document them and declare them in the build configuration.

Ignoring transitive dependencies

One JAR may require other JARs. Adding only the top-level JAR can lead to runtime errors.

Avoid it: Read the library documentation and add all required JARs, or use Maven/Gradle so transitive dependencies are resolved automatically.

Comparisons

ApproachBest forAdvantagesLimitations
IntelliJ module libraryOne or a few local JARs, experiments, legacy projectsQuick to configure in the IDEIDE-specific unless also represented in a build file
Maven dependencyStandard Java applications and librariesRepeatable builds, versions, transitive dependenciesRequires a pom.xml and repository access for remote packages
Gradle dependencyJava projects needing flexible build configurationRepeatable builds and flexible dependency declarationsRequires Gradle build files and basic Gradle knowledge
Copying JAR into lib/ onlyFile storage onlyKeeps the file near the projectDoes not itself add the JAR to the classpath

A module library answers, “How can IntelliJ IDEA use this local JAR now?” Maven and Gradle answer, “How can every developer and build machine obtain the same dependency setup?”

Take Quiz

Cheat Sheet

  • A JAR must be on the classpath before Java can import its classes.
  • Merely placing a JAR in lib/ is not enough.
  • In IntelliJ IDEA: File → Project Structure → Modules → Dependencies → + → JARs or Directories.
  • Add the JAR to the module that uses it.
  • Use Compile scope for most application libraries.
  • Use Test scope for libraries used only by tests.
  • Verify setup by importing a class from the JAR; the import should no longer be unresolved.
  • If the program fails at runtime with NoClassDefFoundError, check the runtime dependency configuration and required dependent JARs.
  • Prefer Maven or Gradle for shared, versioned, or multi-developer projects.
  • Do not manually edit .iml, .ipr, or .iws files unless you have a specific legacy reason; use the IDE settings or build files.

FAQ

How do I add all JAR files from a lib folder in IntelliJ IDEA?

Open Project Structure, select the target module, open Dependencies, choose + → JARs or Directories, and select the required JAR files. If the IDEA version offers a directory or recursive option, verify which JARs were added afterward. For reliable team builds, declare the files in Maven or Gradle instead.

Why is my import still red after I add a JAR?

Check that the JAR was added to the correct module, contains the class you are importing, and has a scope available to that source set. Also verify the package name and refresh or rebuild the project if needed.

Should I edit the .iml file manually to add a library?

Usually no. IntelliJ IDEA manages module configuration through its UI, and build tools manage dependencies through pom.xml or Gradle files. Manual edits can be overwritten or create inconsistent project state.

What dependency scope should I use for an external JAR?

Use Compile when main application code imports the JAR. Use Test when only test code imports it. Use other scopes only when their classpath behavior matches your deployment requirements.

Can IntelliJ IDEA run my code with external JARs?

Yes. A correctly configured module dependency is included on the classpath used by standard IntelliJ IDEA run configurations.

Is a lib folder better than Maven or Gradle?

Not usually. A lib folder can work for a small or legacy project, but Maven and Gradle provide version tracking, dependency downloading, transitive dependency management, and reproducible builds.

What if the JAR depends on other JARs?

Add its required dependencies too. Otherwise, the application may fail when it loads a missing class. Maven and Gradle are especially helpful because they can resolve declared transitive dependencies automatically.

Take Quiz

Mini Project

Description

Create a small Java application that uses a class from a local JAR. This demonstrates the difference between storing a JAR in a lib/ folder and registering it as a module dependency in IntelliJ IDEA.

Goal

Configure a local JAR as a module dependency and call one of its public classes from Main.java.

Requirements

Add a JAR file to a lib/ directory in the project.

Register that JAR through IntelliJ IDEA's module dependency settings.

Create a Main class that imports and uses a public class from the JAR.

Run the program without unresolved-import or missing-class errors.

Take Quiz

Keep learning

Related questions

View more