Skip to content

Build and Profiles

Jin Kwon edited this page Nov 13, 2026 · 1 revision

Build and Profiles

Versions below are those of the working tree (0.6.2-SNAPSHOT); pom.xml and its comments are authoritative.

Java versions

maven.compiler.release (main) 17 — the artifact stays usable on 17
maven.compiler.testRelease 25
Build JDK 25 — a JDK 17 javac cannot do --release 25
Maven the checked-in wrapper, Maven 3.9.11 (./mvnw)

Release-17 bytecode is what the main classes are compiled to. The test suite, built at 25, cannot run on 17, so CI runs a small consumer there instead, against the packaged jar — see Continuous integration.

Two axes

The build has two independent axes, each chosen by a profile: the Jakarta EE generation, and the AssertJ line.

Jakarta EE generation

Jakarta Validation has a single implementation in this build — Hibernate Validator, with Expressly for the expression language — so a profile does not choose an implementation. It chooses a generation, and the versions which move with it.

Profile jakarta.jakartaee-bom jakarta.validation-api Spec Hibernate Validator Expressly jinahyaee-bom-NN
jakartaee-11 (active by default) 11.0.0 3.1.1 3.1 9.1.4.Final 6.0.0 jinahyaee-bom-11:0.0.2
jakartaee-10 10.0.0 3.0.2 3.0 8.0.5.Final 5.0.0 jinahyaee-bom-10:0.0.2
  • The platform BOM is imported in <dependencyManagement> and pins jakarta.validation-api; the POM never states the API version itself.
  • jakarta.ee.generation (11 / 10) is the NN of the generation-suffixed jinahya-* artifacts: jinahyaee-bom-NN, also imported, manages jinahya-validation-utils-NN and jinahya-validation-test-utils-NN, which the tests use for validator helpers. Both are test scope.
  • jakarta.validation.spec.version (3.1 / 3.0) is passed by Surefire to the tests as a system property, so a test can assert which generation it runs against.
  • The defaults in <properties> are jakartaee-11's, so that profile overrides nothing; jakartaee-10 overrides all of them. One source tree serves both generations because 3.1 adds no API member this library uses.
  • Hibernate Validator and Expressly move together: 9 ↔ 6, 8 ↔ 5.

AssertJ line

Profile version.org.assertj
(none) 3.27.7 — what the main classes are compiled against
assertj-4 4.0.0-M1

AssertJ 3 is the line every consumer can run; AssertJ 4 is the target. 4.0.0-M1 is declared binary-incompatible with 3.x, but not in the members this library calls, so the jar built on 3.x runs on either. The default moves to 4.x once 4.0.0 is released (#20).

Name the generation when you name a profile

jakartaee-11 is activeByDefault, and Maven deactivates every activeByDefault profile as soon as any profile is named on the command line. Because the root <properties> already carry the EE 11 values, -P assertj-4 alone still builds against EE 11 — but it drops the jakartaee-11 profile's versions-maven-plugin ranges. Name both, as CI does:

./mvnw test                               # jakartaee-11, AssertJ 3.27.7
./mvnw -P jakartaee-10 test               # Jakarta Validation 3.0
./mvnw -P jakartaee-11,assertj-4 test     # AssertJ 4.0.0-M1
./mvnw -P jakartaee-10,assertj-4 test

Scopes

Scope Dependencies Why
provided jakarta.validation-api, assertj-core the two APIs this library sits between; compiled against, and supplied by the consumer at versions of its choosing
test hibernate-validator, expressly, jinahya-validation-utils-NN, jinahya-validation-test-utils-NN, JUnit Jupiter 5.14.4, Mockito 5.24.0, Lombok 1.18.48, Logback 1.6.5 (SLF4J 2.0.20 via BOM) the engine and the test tooling; nothing in src/main references an implementation

There is no compile or runtime dependency, so the published POM brings nothing onto a consumer's classpath.

Notes from the POM:

  • assertj-core excludes byte-buddy, so Mockito's newer version wins. The exclusion is on the dependency, not in <dependencyManagement>, because a BOM import carries no exclusions.
  • Lombok is on the annotation-processor path of the test compilation only; the main compilation runs no processor.
  • JUnit is held at 5.x because mockito-junit-jupiter 5.24.0 still declares junit-jupiter-api 5.13.4.
  • maven-jar-plugin is pinned (3.5.1) and writes Automatic-Module-Name: com.github.jinahya.assertj.validation.
  • maven-javadoc-plugin registers @apiNote, @implSpec and @implNote, and links to the AssertJ and Jakarta Validation API docs of the active versions.

Keeping versions within a generation

versions-maven-plugin is configured so that bulk updates cannot cross a generation:

  • ignoredVersions hides every pre-release (alpha, beta, M, RC, CR). Besides not tracking someone else's beta, this matters because Maven orders 11.0.0-RC1 below 11.0.0, inside the [10,11) range.
  • each generation profile pins its three axis properties to a major range — jakartaee-11: BOM [11,12), Hibernate Validator [9,10), Expressly [6,7); jakartaee-10: [10,11), [8,9), [5,6). Moving a generation is a deliberate edit, not something versions:update-properties does.

Continuous integration

.github/workflows/maven.yml, on push and pull request against develop:

Job What it runs
build a matrix of jakartaee-11, jakartaee-10, jakartaee-11,assertj-4, jakartaee-10,assertj-4, each ./mvnw -B verify -P <profile> on Temurin 25, fail-fast: false
build, jakartaee-11 entry only additionally ./mvnw -B javadoc:javadoc -Dmaven.javadoc.failOnWarnings=true — the Javadoc builds with zero warnings
java17-consumer packages the jar (built on AssertJ 3) on Temurin 25, then compiles and runs .ci/java17/Java17Consumer.java against it on Temurin 17, for AssertJ 3.27.7 and 4.0.0-M1 × Jakarta Validation 3.0.2 (Hibernate Validator 8) and 3.1.1 (Hibernate Validator 9)
dependency-graph on push only, after build: submits the Maven dependency graph from the default generation

Running locally

./mvnw verify                                   # what CI's default entry runs
./mvnw -B javadoc:javadoc -Dmaven.javadoc.failOnWarnings=true
./mvnw -B -Dmaven.test.skip=true package && .ci/java17/run.sh   # on a JDK 17; -Dassertj.version=… etc. to vary
./mvnw versions:display-property-updates        # within-generation updates only

.mvn/jvm.config adds --add-exports / --add-opens for jdk.compiler internals to the JVM Maven runs in.

Clone this wiki locally