Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add information on Java record support #275

Merged
merged 4 commits into from
Mar 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<format property="current.date" pattern="yyyy-MM-dd"/>
</tstamp>

<property name="bv.version" value="3.1.0-M1" /><!-- e.g. '2.0.0-RC1' -->
<property name="bv.version" value="3.1.0-M2" /><!-- e.g. '2.0.0-RC1' -->
<property name="bv.version.spec" value="3.1" /><!-- The major.minor of the specification (no service releases) -->
<property name="bv.version.qualifier" value="Draft" /><!-- e.g. ' (Early Draft 1)' - be careful about the space before the qualifier -->
<property name="bv.revdate" value="${current.date}" /> <!-- Replace with fixed date when releasing -->
Expand All @@ -26,7 +26,7 @@
<property name="hibernate-asciidoctor-theme.version" value="1.0.2.Final" />
<property name="hibernate-asciidoctor-extensions.version" value="1.0.2.Final" />
<property name="maven-dependency-plugin.version" value="2.10" />
<property name="base.name" value="bean-validation-specification"/>
<property name="base.name" value="validation-specification"/>
<property name="spec.styles.dir" value="${basedir}/styles"/>
<property name="document.basedir" value="${basedir}"/>
<property name="validation-api.sourcedir" value="target/validation-api" />
Expand Down Expand Up @@ -177,7 +177,7 @@
</exec>
</target>

<!-- Creates the tck-audit.xml file; Run after updates to the spec and copy+commit to the beanvalidation-tck repository -->
<!-- Creates the tck-audit.xml file; Run after updates to the spec and copy+commit to the validation-tck repository -->
<!-- Converts the spec to DocBook before as that's the input format for the audit file creation -->
<target name="create-tck-audit-file" depends="determine-git-revision, render-docbook">
<tstamp>
Expand Down
1 change: 1 addition & 0 deletions sources/builtin-constraints.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//
// License: Apache License, Version 2.0
// See the license.txt file in the root directory or <http://www.apache.org/licenses/LICENSE-2.0>.
:validation-api-source-dir: ../target/validation-api/

[[builtinconstraints]]

Expand Down
5 changes: 5 additions & 0 deletions sources/changelog.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ Names used under the JCP for specifications are preserved in the Changelog secti

[source]
....
3.1.0 (2024-01-26)
------------------
** New Feature
* EE11, clarify the requirements around Java records and add basic TCK tests for them.

3.0.0 (2020-07-03)
------------------
** New Feature
Expand Down
75 changes: 74 additions & 1 deletion sources/constraint-declaration-validation.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
//
// License: Apache License, Version 2.0
// See the license.txt file in the root directory or <http://www.apache.org/licenses/LICENSE-2.0>.
:validation-api-source-dir: ../target/validation-api/
:spec-examples-source-dir: ../spec-examples/src/test/java/

[[constraintdeclarationvalidationprocess]]

Expand Down Expand Up @@ -1014,7 +1016,7 @@ Note that declaring these constraints does not automatically cause their validat

[TIP]
====
In order to use constraint annotations for method or constructor parameters, their element type must be [varname]`ElementType.PARAMETER`. In order to use constraint annotations for cross-parameter validation or on the return values of methods or constructors (see the following sections), their element type must be [varname]`ElementType.METHOD` respectively [varname]`ElementType.CONSTRUCTOR`. All built-in constraints support these element types and it is considered a best practice to do the same for custom constraints.
In order to use constraint annotations for method or constructor parameters, their element type must be [varname]`ElementType.PARAMETER`. In order to use constraint annotations for cross-parameter validation or on the return values of methods or constructors (see the following sections), their element type must be [varname]`ElementType.METHOD` respectively [varname]`ElementType.CONSTRUCTOR`. All built-in constraints support these element types, and it is considered a best practice to do the same for custom constraints.
====

[[constraintdeclarationvalidationprocess-methodlevelconstraints-parameterconstraints-crossparameterconstraints]]
Expand Down Expand Up @@ -2462,3 +2464,74 @@ the validation routine will return the following failures:


As the [classname]`First` and [classname]`Second` groups pass without failure, the [classname]`Last` group is going through validation.

Java records are supported by {spec-name-bv}. The following examples demonstrate how to use records with {spec-name-bv} constraints.

.Example record constuctor parameter constraint and constructor return value constraint
====

[source, JAVA]
----
@Target({ METHOD, CONSTRUCTOR, ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = ValidStockItemRecord.Validator.class)
@Documented
public @interface ValidStockItemRecord {
String message() default "{ValidStockItem.message}";

Class<?>[] groups() default { };

Class<? extends Payload>[] payload() default { };

public class Validator implements ConstraintValidator<ValidStockItemRecord, StockItemRecord> {

@Override
public boolean isValid(StockItemRecord object, ConstraintValidatorContext context) {
return false;
}
}
}

public record StockItemRecord(@NotNull String name) {
@ValidStockItemRecord
public StockItemRecord {
}
}
----
Here the constructor parameter constraint is declared on the record components list and the return value constraint is declared on the compact constructor.

====

.Example record cross-parameter constraint with parameter constraints
====

[source, JAVA]
----

@Target({ METHOD, CONSTRUCTOR, ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = MyCrossParameterConstraintValidator.class)
@Documented
public @interface MyCrossParameterConstraint {
String message() default "{MyCrossParameterConstraint.message}";

Class<?>[] groups() default { };

Class<? extends Payload>[] payload() default { };

@Target({ METHOD, CONSTRUCTOR, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Documented
@interface List {
MyCrossParameterConstraint[] value();
}
}

public record ComplexStockItemRecord(@NotNull String name, @NotNull String description) {
@MyCrossParameterConstraint
public ComplexStockItemRecord {
}
}
----
Here the constructor parameter constraints are declared on the record components list and the cross-parameter constraint is declared on the compact constructor.
====
2 changes: 2 additions & 0 deletions sources/constraint-definition.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
//
// License: Apache License, Version 2.0
// See the license.txt file in the root directory or <http://www.apache.org/licenses/LICENSE-2.0>.
:validation-api-source-dir: ../target/validation-api/
:spec-examples-source-dir: ../spec-examples/src/test/java/

[[constraintsdefinitionimplementation]]

Expand Down
2 changes: 2 additions & 0 deletions sources/constraint-metadata.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
//
// License: Apache License, Version 2.0
// See the license.txt file in the root directory or <http://www.apache.org/licenses/LICENSE-2.0>.
:validation-api-source-dir: ../target/validation-api/
:spec-examples-source-dir: ../spec-examples/src/test/java/

[[constraintmetadata]]

Expand Down
7 changes: 7 additions & 0 deletions sources/integration.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
//
// License: Apache License, Version 2.0
// See the license.txt file in the root directory or <http://www.apache.org/licenses/LICENSE-2.0>.
:validation-api-source-dir: ../target/validation-api/
:spec-examples-source-dir: ../spec-examples/src/test/java/

[[integration]]

Expand Down Expand Up @@ -272,6 +274,11 @@ The {spec-name-di} interceptor binding facility does not directly support this,
It is recommended to only intercept methods and constructors that are both constrained and validated according to the rules defined at <<integration-general-executable>>. <<validationapi-triggeringmethodvalidation>> gives examples how the metadata API can be used to determine whether or not a method is constrained (regardless of the filtering rules of [classname]`@ValidateOnExecution`).
====

==== Java records
Java records are a new language feature introduced in Java 14. They are classes that are designed to be immutable and have a concise syntax for declaring properties and methods. They are unproxyable bean types as per {spec-name-di} since they are final and have no non-private constructor with no parameters. Because of this, {spec-name-di} beans that are records are not validated by default. To enable validation of records, one would need to create a producer method that performs the validation, or utilize some bytecode enhancement to intercept the constructor call and perform the validation. There are no requirements for {spec-name-bv} providers to support validation of records automatically in {spec-name-di} environments.

[[integration-dependencyinjection-configuration]]

[[integration-persistence]]
=== {spec-name-persistence} 2.0 integration

Expand Down
2 changes: 1 addition & 1 deletion sources/introduction.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ As of version 1.1, {spec-name-bv} constraints can also be applied to the paramet
[[introduction-requirements]]
=== Required Java version

The specification uses Java 8 language features. There is no requirement that implementations be compatible with Java language versions prior to 8.
The specification uses Java 17 language features. There is no requirement that implementations be compatible with Java language versions prior to 17.

[[introduction-documentorganization]]
=== How this document is organized
Expand Down
2 changes: 2 additions & 0 deletions sources/validation-api.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
//
// License: Apache License, Version 2.0
// See the license.txt file in the root directory or <http://www.apache.org/licenses/LICENSE-2.0>.
:validation-api-source-dir: ../target/validation-api/
:spec-examples-source-dir: ../spec-examples/src/test/java/

[[validationapi]]

Expand Down
1 change: 1 addition & 0 deletions sources/value-extractor-definition.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//
// License: Apache License, Version 2.0
// See the license.txt file in the root directory or <http://www.apache.org/licenses/LICENSE-2.0>.
:validation-api-source-dir: ../target/validation-api/

[[valueextractordefinition]]
== Value extractor definition
Expand Down
7 changes: 7 additions & 0 deletions sources/whatsnew.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@
Names used under the JCP for specifications are preserved in the What's new section for versions released prior to the move to Jakarta EE in order to preserve historical accuracy.
====

[[whatsnew-31]]
=== What's new in 3.1
Two minor changes are introduced in Jakarta Validation 3.1:

* Jakarta Bean Validation has been renamed to simply Jakarta Validation.
* Support for Java records has been clarified.

[[whatsnew-30]]
=== What's new in 3.0

Expand Down
4 changes: 2 additions & 2 deletions spec-examples/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
<version>3.0.0-SNAPSHOT</version>
<version>3.1.0-M2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
Expand Down