This page lists everything that changes for a project that uses the 5.x generator. Link to it by its path, guide/migration.html; each section has a fixed anchor, so a link to migration.html#coordinates keeps working.
The goal of 6.0.0 is that a project on Java 17 or newer moves by a version bump alone. Each change below is either covered by the bridge jars or is one you make when you choose to.
What to do
-
Check the JDK. A project on Java 17 or newer can move. A project that runs on Java 11 stays on 5.x, see Java 11 users.
-
Bump the version of the generator to 6.0.0. Your 5.x coordinates still resolve: the bridge jars
hamcrest-matcher-generator-annotationprocessorandhamcrest-matcher-generator-dependenciesdepend onhamcrest-matcher-generator, see New coordinates and bridge jars. -
Compile and run the tests. A test that pins the exact text of a mismatch message needs an update, see the new form of the messages.
-
Make the optional changes when you choose to: the annotation, see @GenerateMatchers; a direct import of
BeanPropertyMatcher, see its new package; thejavax.annotationAPI, see javax.annotation; and the opt-in features, see opt-in features.
Java 11 users stay on 5.x
The processor, the runtime and the generated code of 6.0.0 need Java 17: the classes are compiled for Java 17 and need a Java 17 runtime. A project that runs on Java 11 stays on 5.x.
New coordinates and bridge jars
The group ID stays io.github.marmer.testutils. 6.0.0 has neutral artifact names for the parts that are not Hamcrest specific, and the Hamcrest artifact keeps its name:
| Artifact | Role in 6.0.0 |
|---|---|
|
The Hamcrest backend and the |
|
The configuration annotation |
|
The shared property model and the processor entry point. The backends pull it in; you do not declare it. |
|
The AssertJ backend. New in 6.0.0, opt-in. |
|
The Kotlin DSL, used with KAPT. New in 6.0.0, opt-in. |
|
The 5.x artifacts, now bridge jars. They contain no code and depend on |
The bridge jars let a 5.x build resolve without a change of coordinates. Keep the scope you declared for a 5.x artifact, as the scope advice in the getting started chapter describes: the Hamcrest backend arrives transitively with the scope of the bridge jar. The reason is the compiler plugin: maven-compiler-plugin before 3.12 does not follow a relocation POM in its processor path, so the 5.x artifacts are jars and not relocations. A project that keeps the 5.x coordinates gets the Hamcrest backend through them, and the processor arrives with it.
The Maven dependencies name the artifacts as follows, in the snippet of the Hamcrest example:
<dependency>
<groupId>io.github.marmer.testutils</groupId>
<artifactId>hamcrest-matcher-generator</artifactId>
<version>${hamcrest-matcher-generator.version}</version>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest</artifactId>
</dependency>
@GenerateMatchers instead of @MatcherConfiguration
The configuration annotation is @GenerateMatchers, in the package io.github.marmer.matchergenerator.annotations. It has the attributes of the 5.x annotation, value and generation, and a new attribute exclude that leaves out types of the selection:
import io.github.marmer.matchergenerator.annotations.GenerateMatchers;
/** Generates a matcher for every model class in {@code example.hamcrest.model}. */
@GenerateMatchers("example.hamcrest.model")
public final class HamcrestConfiguration {}
The 5.x @MatcherConfiguration stays as a deprecated alias in its old package, io.github.marmer.testutils.generators.beanmatcher.dependencies. It is a full alias: it has the same attributes, including exclude, so you can use the new feature before you rename the annotation. Its retention is source only, so it leaves no trace in the compiled classes, as in 5.x; the new @GenerateMatchers has source retention too.
Two behaviours differ between the two annotations. A value that matches no type is a compiler error for @GenerateMatchers and a warning for the alias, which keeps 5.x configurations compiling. Renaming the annotation therefore makes a misspelled type name stop the build.
BeanPropertyMatcher has a new package
The runtime class BeanPropertyMatcher moved to the package io.github.marmer.matchergenerator.hamcrest, in the artifact hamcrest-matcher-generator. In 5.x it was in io.github.marmer.testutils.generators.beanmatcher.dependencies.
Generated matchers use the class, so a recompile of the project brings the generated code to the new package. A project changes its own code only if it imports BeanPropertyMatcher directly, which the generated API does not require. Such an import needs the new package name.
javax.annotation is no longer transitive
6.0.0 no longer depends on javax.annotation:javax.annotation-api. The processor uses only javax.annotation.processing.Generated, which the JDK provides, so the generator needs nothing more. The 5.x artifact hamcrest-matcher-generator-annotationprocessor did bring the API in.
If your code uses javax.annotation types that reached your classpath through the generator, declare javax.annotation:javax.annotation-api in your own build with the version you choose. The generated code does not need it.
Opt-in features
Everything in this list is off unless you use it. Your existing tests keep compiling and passing without any of them:
-
Completeness check.
checkingAllProperties()on a matcher, andignoringX()for a property you leave out. Chapter Completeness check describes the rule for both backends. -
Reference objects.
isXLike(reference)compares every property with a reference object, as the Hamcrest backend chapter describes. -
Exclusions. The
excludeattribute of@GenerateMatchers, and of the alias, as described above. -
AssertJ. The
assertj-assertion-generatorartifact generates an assertion per type, as the AssertJ backend chapter describes. It runs next to the Hamcrest backend. -
Kotlin DSL. The
hamcrest-matcher-generator-kotlinartifact generates the DSL under KAPT, as the Kotlin chapter describes.
The new form of mismatch messages
A 5.x matcher joined its failing checks on one line, separated by ` and `. 6.0.0 writes one line per failing check, each with its property path, nested paths included, as the mismatch messages chapter shows. This is a breaking change for a test that parses a message or pins its exact text. Such a test must be updated to the new form. A test that only checks that an assertion fails is not affected.
What does not change
The generated class names, their packages and the methods isX(), withX and resetX keep their 5.x names. ignoringX() and checkingAllProperties() are new in 6.0.0. A 5.x project that neither imports BeanPropertyMatcher directly nor uses javax.annotation types from the generator compiles after a version bump.
Next steps
-
Getting started for the setup of a new project.
-
Configuration for the attributes of
@GenerateMatchers.