Split Packages on Java 9 Modules

December 3, 2017

Java 9 finally introduced a proper module system, The Java Platform Module System (JPMS), formerly known as Project Jigsaw.
One of its main goals is to “make it easier for developers to construct and maintain libraries and large applications”, and it suppose to solve some of the issues with conflicting libraries and versions, a.k.a. Jar Hell.
You can read here about JPMS basics and here about the way to manage them with gradle.

One of the restrictions when working with JPMS is that a package can not be exported from more one module (video).
For example, if one module (dependency.api) contains the class io.github.msayag.lib.Something, another module (dependency.impl)can contain the class io.github.msayag.lib.KindOfSomething because they are both in the package io.github.msayag.lib.

Split Package

IntelliJ Error

Solution 1: Move

The problematic modules are under your control The solution is this case is usually simple: change the package of the conflicting classes. For example, move KindOfSomething to package io.github.msayag.lib.impl

Solution 2: Upgrade

A package might be split between 2 libraries that are out of your control.
For example, I have a project that uses log4j and thus require the libraries log4j.api and _log4j.core.
Unfortunately, the used version is 2.7, which is old and doesn’t support module system.

Log4J 2.7 Conflict

Log4J 2.7 Split Package

One solution may be to upgrade the library to a newer version that do support the modules (log4j 2.10.0).

Log4J 2.10.0

Solution 3: Unsplit

If such version can not be used, because of the project’s limitation or if such a version does not exist, a more complicated solution might have to be applied. Since the problem is with classes from different jars, perhaps it can be worked around by merging the conflicting jars into a bigger one that contains the content of both. To do so, extract the 2 original jars to the same location and pack them back together as a new jar or module.

1
2
3
4
5
mkdir log4j-bridge
cd log4j-bridge
jar -xvf /path/to/log4j-api-2.7.jar
jar -xvf /path/to/log4j-core-2.7.jar
jar -cf log4j-bridge-2.7.jar *

Download .zip Download .tar.gz View on GitHub

Tags

kafka avro docker spring webflux java9 modules jpms