Question
Add External JAR Files to an IntelliJ IDEA Java Project
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:
- Open File → Project Structure.
- Select Modules.
- Select the module that contains your Java source code.
- Open the Dependencies tab.
- Click + and choose JARs or Directories.
- Select one or more JAR files in
lib/. - Choose the appropriate dependency scope, usually Compile.
- 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.
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.
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:
- IntelliJ IDEA reads the module's dependency list.
- It finds the configured JAR and indexes the classes inside it.
- The import statement is resolved to
Greeterin that JAR. - During compilation,
javacreceives the JAR as part of its classpath. new Greeter()creates an object from the external library.greeter.greet("Sam")calls code packaged in the JAR.- 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 . 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.
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:
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.
Prefer a or file. If local JARs must be committed, document them and declare them in the build configuration.
Comparisons
| Approach | Best for | Advantages | Limitations |
|---|---|---|---|
| IntelliJ module library | One or a few local JARs, experiments, legacy projects | Quick to configure in the IDE | IDE-specific unless also represented in a build file |
| Maven dependency | Standard Java applications and libraries | Repeatable builds, versions, transitive dependencies | Requires a pom.xml and repository access for remote packages |
| Gradle dependency | Java projects needing flexible build configuration | Repeatable builds and flexible dependency declarations | Requires Gradle build files and basic Gradle knowledge |
Copying JAR into lib/ only | File storage only | Keeps the file near the project | Does 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?”
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.iwsfiles 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.
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.
Keep learning
Related questions
Avoiding Java Code in JSP with JSP 2: EL and JSTL Explained
Learn how to avoid Java scriptlets in JSP 2 using Expression Language and JSTL, with examples, best practices, and common mistakes.
Call a Method After a Delay in Android Java
Learn how to run Java code after a delay in Android using Handler.postDelayed, manage the main thread, and cancel callbacks safely.
Choosing a @NotNull Annotation in Java: Validation vs Static Analysis
Learn how Java @NotNull annotations differ, when to use each one, and how to choose between validation, IDE hints, and static analysis tools.