Module resolution and module path

1. Introduction

Before Java 9, the scan of the whole classpath was required to search for a type. The classpath is a flat list of types. In Java 9, the modules are resolved from module path which contains only modules. The Java runtime and compiler are able to look for the module in the module path when looking for types.

2. Module resolution process

When you run a Java application which is packaged as a module, you need to resolve all of its dependencies. In the module resolution process, a root module is chosen from the dependency graph. Then all the required modules are marked as resolved. The process can be explained in following steps:

  1. Select a single root module and add it to the resolved set.
  2. Find all required modules (requires or requires transitive in module-info.java) and add to the resolved set.
  3. Repeat step 2 for each new module added to the resolved set in step 2.

3. Important points

Important points about module resolution:

  • If two modules with the same name are found in the process then it results in an error. Note that this is not at the runtime like the classloading failures before Java 9.
  • Only one module on the module path can export a package.
  • Version (of dependencies like in pom.xml) has no role to play in module resolution process.
  • Cyclic Dependency is not allowed between the modules and hence Module Graph should not contain cycles.

4. Conclusion

A quick recap:

Module resolution is the process of finding the exact module needed by your code, considering a dependency graph and a chosen root module.

Module path is a set of directories or JAR files containing Java modules. It’s where the Java runtime (JVM) searches for modules during program execution. Unlike the classpath (used in pre-Java 9 versions), the module path can only contain modules, not individual class files. You can specify the module path using the --module-path option when running the Java application.