IntelliJ IDEA 2017.2 Help

Working with module dependencies

What are module dependencies?

Module dependencies are the things that a module uses and, consequently, depends on.

The module dependencies may include:

  • An SDK which, if present in module dependencies, is referred to as the module SDK.
  • Libraries: collections of archives (JARs) and directories with class files, sources and documentation.
  • Other modules belonging to the same project.

When you compile or run your code, the module dependencies are used to form the classpath for the compiler or JVM. (Native Library Locations, if any, are added to java.library.path rather than the classpath.)

Where do I manage module dependencies?

Most of the tasks related to working with module dependencies are performed in the Project Structure dialog (File | Project Structure): select Modules, select the module of interest, and then select Dependencies.

libs project structure module libs

Use the following icons and context menu commands:

libs project structure module dependencies

Adding dependencies

Next to the list of dependencies, click add and select:

  • JARs or directories. In the dialog that opens, select the files and folders to be added to the dependencies. (For each selected file and folder, an unnamed module library is created.)
  • Library. In the dialog that opens, select one or more libraries and click Add Selected. (You can also create a new library: New Library and then add it to the dependencies: Add Selected).
  • Module Dependency. In the dialog that opens, select the modules to be added to the dependencies.

See also, Adding a global or project library to module dependencies.

Sorting the list of dependencies

You can sort the dependencies by their names (the central column) and scopes by clicking the cells in the header row.

  • First click. The list is sorted by the corresponding column in the ascending order. The sorting marker appears in the cell: sortMarkerAsc.
  • Second click. The order changes to descending; the sorting marker changes to sortMarkerDesc.
  • Third click. The initial unsorted state is restored.

When the list is sorted, you cannot change the order of dependencies.

Order of dependencies

The module dependencies are processed in the order they appear in the corresponding list.

At compile time, the order of items in the list defines the order in which the compiler (javac) looks for the classes to resolve the corresponding references. At runtime, this list defines the order in which the JVM searches for the classes to be loaded.

Using library patches. If you want to use patches to certain libraries, these patches should be placed in the list before the main libraries. Otherwise, new versions of the classes (contained in the patches) will be ignored.

Classpath, bootclasspath and the JDK position. For compilation, the positions of items in the list in relation to the module JDK may be important:

  • The items that appear after the JDK are translated into the module classpath entries. Most of the libraries that you normally deal with should go there.
  • The items that appear before the JDK correspond to the module bootclasspath entries.

    For compilation to succeed, certain libraries (e.g. ones having to do with the JDK itself and its extensions) must be included in the module bootclasspath. So, such libraries must appear in the list before the JDK.

    The use of such libraries, however, may be necessary in a very limited number of special cases. Thus, for most of your modules, the JDK will (and should) be the first item in the list of dependencies.

Controlling compilation and runtime classpaths for sources and tests

You can specify whether a dependency should be included in the classpath 1) when compiling the module sources 2) when compiling the module test sources 3) when running the compiled sources 4) when running the tests. You do that by selecting one of the following options for the dependency scope (the Scope column on the Dependencies tab):

  • Compile. The dependency is included in the classpath for your sources and test sources at the compilation and run phases.
  • Test. The dependency is included in the classpath only when compiling and running your test sources.
  • Runtime. The dependency is included in the classpath only when running your sources and test sources.
  • Provided. For your sources, the dependency is included in the classpath only at the compilation phase. This is useful when there is a container (e.g. a web container) that provides the corresponding dependency at runtime.

    For your test sources, the dependency is included in the classpath both at the build and run phases.

    Application server libraries, normally, are included in the dependency lists with the scope Provided.

The following table summarizes the classpath information for the possible dependency scopes.

ScopeSources,
when compiled
Sources,
when run
Tests,
when compiled
Tests,
when run
Compile++++
Test--++
Runtime-+-+
Provided+-++

Processing dependencies for test sources. Note that IntelliJ IDEA is different from some other build tools (e.g. Gradle and Maven) in the way it processes dependencies for test sources.

If your module (say, module A) depends on another module (module B), IntelliJ IDEA assumes that the test sources in A depend not only on the sources in B but also on its test sources. Consequently, the test sources of B are also included in the corresponding classpaths.

Exporting dependencies to compilation classpaths of other modules

Say, you have a module (module A) that depends on another module (module B).

At runtime, all the dependencies of B are included in the classpath of A.

As for the compilation classpath of A, you have two choices for each of the dependencies of B. (For illustrating, let's assume that B has a library L in its dependencies.)

  • L is included in the classpath of A if, in the dependencies of B, it has the Export option on.
  • L is not included in the classpath of A if the L's Export option is off.

To turn the Export option on and off, use the check boxes in the Export column on the Dependencies tab.

Note that the dependency scopes may change when exported. Let's assume that:

  • The scope of the dependency of A on B is Compile.
  • The scope of the dependency of B on L is Test.

If L has the Export option on, then the scope of the dependency of A on L will effectively be Test.

This and also some other interesting practical cases are listed in the following table.

A on B dependency,
specified scope
B on L dependency,
specified scope
A on L dependency,
resulting scope
CompileCompileCompile
CompileTestTest
TestCompileTest
TestTestTest
Last modified: 29 November 2017

See Also