User:Leo3418/Hamcrest 2.x migration

This page explains the proposal to migrate packages in the Gentoo repository that use Hamcrest 1.x to Hamcrest 2.x.

Problem statement
Hamcrest released version 2.1 to provide the org.hamcrest JPMS module (referred to as "module" below), which other Java projects can use to integrate with the JPMS.

When another Java project depends on the org.hamcrest module, building the project requires Hamcrest 2.x, and only 2.x, to be in the class path.


 * Using Hamcrest 1.x in place of 2.x would trigger an error like the following:

{{GenericCmd|output= error: the unnamed module reads package org.hamcrest.internal from both hamcrest.core and org.hamcrest assertj-core/src/main/java9/module-info.java:13: error: module org.assertj.core reads package org.hamcrest.internal from both org.hamcrest and hamcrest.core module org.assertj.core { ^ }}
 * Hamcrest 1.x must not be in the class path. Having both 1.x and 2.x in the class path would result in the following errors:

Under the context of Gentoo Java packages, it is easy to ensure that Hamcrest 2.x is in the classpath when a package needs it, but it is difficult to avoid having both 1.x and 2.x in the classpath. A real example is AssertJ Core 3.24.2, which depends on both JUnit 4.13.2 and Hamcrest 2.2. JUnit 4.13.2 depends on Hamcrest 1.3. Therefore, the class path will contain both version 1.3 and version 2.2, leading to the aforementioned errors.

To resolve this problem, packages that depend on Hamcrest 1.x should be migrated to 2.x to satisfy the requirement that 2.x must be the exclusive Hamcrest version in the class path.

Feasibility
According to the Hamcrest upstream, the API of Hamcrest 2.x "has not changed since Hamcrest 1.3", so Hamcrest 2.x is supposed to be a compatible drop-in replacement for 1.3, or maybe even 1.x.

One exception, as the upstream noted, is the org.hamcrest.Factory annotation's removal. The upstream said that the annotation "should not be used in client code", so ideally, this should not be a problem. In reality, at least one known example of a Java project that uses the annotation exists, which is JUnit 4.13.2. Compiling JUnit 4.13.2 with Hamcrest 2.2 fails due to these errors:

Therefore, the migration would require some Gentoo downstream changes to either Hamcrest 2.x or Java projects that depend on Hamcrest 1.x, so the issues pertaining to org.hamcrest.Factory can be resolved.

Other parties' reactions
This section covers the following things, which potentially affect whether the migration should be performed, and how the migration should be executed:
 * Whether the Hamcrest upstream has any plans to reinstate the org.hamcrest.Factory annotation
 * Whether those Java projects that depend on Hamcrest 1.x plan to upgrade to 2.x
 * Other distributions' resolution to this problem

Hamcrest upstream
The Hamcrest upstream consciously removed the org.hamcrest.Factory annotation before releasing 2.1 despite a related user inquiry, so they are unlikely to add the annotation back. If someone had requested Hamcrest to add the annotation back, it is reasonable to infer that the upstream would disregard the request and respond that the Java packages that use Hamcrest was the party that is responsible to resolve this issue and should eliminate any uses of the annotation.


 * https://github.com/hamcrest/JavaHamcrest/issues/224#issuecomment-446984317: A user commented that org.hamcrest.Factory was no longer available.
 * https://github.com/hamcrest/JavaHamcrest/issues/224#issuecomment-446989079: A Hamcrest project member replied with regards to the user's comment, saying "you shouldn't need it".

With regards to JUnit 4.13.2, the Hamcrest upstream provided an upgrade guide for Gradle and Maven projects that use JUnit 4.13.2. The guide is not applicable to Gentoo as Gentoo Java packages typically do not use Gradle or Maven to build a project, even if the project's build system is Gradle or Maven.

JUnit upstream
The JUnit 4 project issue tracker has a ticket for Hamcrest 2.2 upgrade, but the JUnit upstream has not made any visible progress on resolving the ticket yet.

Debian
Debian builds JUnit 4.13.2 with Hamcrest 2.2. They patch both JUnit and Hamcrest to fix build issues. In particular, the Hamcrest patch adds back the org.hamcrest.Factory annotation to Hamcrest 2.2.