arrow-kt / arrow-kt/arrow

`arrow-exception-utils` and `arrow-core` split the `arrow.core` package, which breaks JPMS consumers

Open
#3,965 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Kotlin
Stars
6.6k
Forks
472
Avg merge
3d 49m
Merged PRs (30d)
4

Description

## What happened

Since 2.2.0, `arrow-core-jvm` depends on the new artifact `arrow-exception-utils-jvm`. That artifact
keeps its classes in the `arrow.core` package:

```
$ unzip -l arrow-exception-utils-jvm-2.2.3.jar
arrow/core/NonFatalKt.class
arrow/core/NonFatalKt__NonFatalKt.class
arrow/core/NonFatalOrThrowKt.class
arrow/core/ThrowableUtilsKt.class

$ unzip -p arrow-exception-utils-jvm-2.2.3.jar META-INF/MANIFEST.MF
Automatic-Module-Name: arrow.exception.utils
```

`arrow-core-jvm` carries `Automatic-Module-Name: arrow.core` and also contains the `arrow.core`
package. So two modules on the module path own one package. The Java module system rejects that as a
split package, and every consumer with a `module-info.java` fails to compile or to start as soon as
both JARs end up on the module path:

```
error: module arrow.atomic reads package arrow.core from both arrow.exception.utils and arrow.core
error: module arrow.annotations reads package arrow.core from both arrow.exception.utils and arrow.core
error: module de.saxsys.mvvmfx reads package arrow.core from both arrow.exception.utils and arrow.core
src/main/java/module-info.java:1: error: module com.example.app reads package arrow.core from both arrow.exception.utils and arrow.core
module com.example.app {
^
```

The failure is not limited to modules that `requires arrow.core`. An automatic module reads every
other automatic module, so any application module that requires one automatic module (in the example
above, MvvmFX) pulls both Arrow modules into its readability graph and hits the split package.

## Reproduction

1. A JPMS application module with a `module-info.java`.
2. `implementation("io.arrow-kt:arrow-core:2.2.3")` plus any dependency that is an automatic module.
3. Compile with the module path in use (`javac --module-path ...`).

Removing `arrow-exception-utils-jvm` is not an option, because `arrow-core` calls `NonFatal` and the
throwable helpers at runtime.

## Versions

* Broken: 2.2.0, 2.2.1, 2.2.2, 2.2.3 and 2.3.0-alpha.1 through 2.3.0-alpha.4 - the package layout of
`arrow-exception-utils-jvm` is unchanged in all of them.
* Working: 2.1.2 and earlier, where `arrow-exception-utils` did not exist yet.

Tested against JDK 25 with Gradle and `org.javamodularity.moduleplugin`, but nothing about the
problem is specific to that setup - it is the artifact layout.

## Possible resolutions

1. Move the classes of `arrow-exception-utils` into their own package, e.g. `arrow.core.exception`,
and keep type aliases in `arrow.core` inside `arrow-core` itself.
2. Give `arrow-exception-utils` the same `Automatic-Module-Name` as `arrow-core`. That silences the
split package check, but two JARs claiming one module name is its own problem.
3. Fold the four classes back into `arrow-core-jvm`.

## Workaround for consumers

Patch the extra JAR into the `arrow.core` module so it is no longer a module of its own:

```
--patch-module arrow.core=/arrow-exception-utils-jvm-2.2.3.jar
```

This has to be repeated for compilation, tests and the runtime launcher, and the JAR must be kept off
the module path everywhere.

Contributor guide

Open the contributing guide

Research direction

Start by inspecting the arrow-exception-utils-jvm and arrow-core-jvm artifact contents and their Automatic-Module-Name metadata. Reproduce the failure with a JPMS application and javac --module-path, then determine which listed resolution fits the project. Done means both artifacts can be used by module-path consumers without a split-package error at compilation or runtime.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, kotlin
Domain
build-system, devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.