Erasmus is not on Maven Central yet, so getting started means building it from source once, then using it like any Jakarta Validation provider — the API is 100 % the standard one.
Prerequisites
-
Java 25 (Temurin recommended)
-
Maven 3.9.16 — pinned via
.sdkmanrcin the repo (sdk env) -
io.vidocq:vidocq-parent:0.3.0-SNAPSHOTinstalled in your local Maven repository — the Erasmus reactor inherits from it with an emptyrelativePath, so a fresh clone does not build without it:
git clone https://codefloe.com/Vidocq/vidocq-parent.git
cd vidocq-parent
./mvnw -ntp install
Step 1 — Build from source
git clone https://codefloe.com/Vidocq/erasmus.git
cd erasmus
./mvnw -ntp install -DskipTests
This installs the 0.3.0-SNAPSHOT artifacts into your local repository.
Step 2 — Maven coordinates
<dependency>
<groupId>io.vidocq.erasmus</groupId>
<artifactId>erasmus-api</artifactId>
<version>0.3.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>io.vidocq.erasmus</groupId>
<artifactId>erasmus-core</artifactId>
<version>0.3.0-SNAPSHOT</version>
<scope>runtime</scope>
</dependency>
erasmus-api re-exposes the Jakarta Validation API (requires transitive jakarta.validation); erasmus-core is the engine, discovered at runtime through the spec’s ValidationProvider service — your code never touches an Erasmus class.
Step 3 — Declare the modules
module com.acme.orders {
requires jakarta.validation;
// erasmus-core is a runtime-only provider: no requires needed —
// service binding finds it on the module path.
}
Step 4 — Constrain a bean
package com.acme.orders;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
public class Person {
@NotNull
@Size(min = 2, max = 20)
private String name;
public Person(String name) { this.name = name; }
public String getName() { return name; }
}
Step 5 — Validate
import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import jakarta.validation.ValidatorFactory;
import java.util.Set;
try (ValidatorFactory factory = Validation.buildDefaultValidatorFactory()) {
Validator validator = factory.getValidator();
Set<ConstraintViolation<Person>> violations = validator.validate(new Person("X"));
violations.forEach(v ->
System.out.println(v.getPropertyPath() + ": " + v.getMessage()));
// name: size must be between 2 and 20
}
buildDefaultValidatorFactory() finds Erasmus through the standard provider discovery — the same code runs unchanged on any compliant implementation.
Next steps
-
Usage — custom constraints, composition, message interpolation.
-
Concepts — how the engine models constraint metadata.
-
TCK status — what is covered today, what is coming.