Repository: joelittlejohn/jsonschema2pojo
Pull request #1280 (2021-07-06 19:26:23)

Support usage of JSR-303 annotations from 'jakarta.validation' package
- As suggested in https://github.com/joelittlejohn/jsonschema2pojo/issues/1271#issuecomment-871246569 - added `useJakartaValidation` (default `false`) as a new configuration option
- Using `apache bval` for `javax.validation` and `hibernate-validator` for `jakarta.validation` in integration tests
- Unit tests are done using `@Parameterized` to check both cases (`javax.validation` and `jakarta.validation`) alternatives could be
  - duplicate test methods with addition of `useJakartaValidation` configuration option
  - duplicate test classes with addition of `useJakartaValidation` configuration option


Patch:
diff --git a/jsonschema2pojo-ant/src/main/java/org/jsonschema2pojo/ant/Jsonschema2PojoTask.java b/jsonschema2pojo-ant/src/main/java/org/jsonschema2pojo/ant/Jsonschema2PojoTask.java
index 6928eb69..8631cb72 100644
--- a/jsonschema2pojo-ant/src/main/java/org/jsonschema2pojo/ant/Jsonschema2PojoTask.java
+++ b/jsonschema2pojo-ant/src/main/java/org/jsonschema2pojo/ant/Jsonschema2PojoTask.java
@@ -195,6 +195,7 @@ public class Jsonschema2PojoTask extends Task implements GenerationConfig {
     
     private boolean includeGeneratedAnnotation = true;
 
+    private boolean useJakartaValidation = false;
     /**
      * Execute this task (it's expected that all relevant setters will have been
      * called by Ant to provide task configuration <em>before</em> this method
@@ -953,7 +954,7 @@ public class Jsonschema2PojoTask extends Task implements GenerationConfig {
     public void setSourceSortOrder(SourceSortOrder sourceSortOrder) {
         this.sourceSortOrder = sourceSortOrder;
     }
-    
+
     /**
      * Sets the 'useInnerClassBuilders' property of this class
      *
@@ -963,6 +964,16 @@ public class Jsonschema2PojoTask extends Task implements GenerationConfig {
         this.useInnerClassBuilders = useInnerClassBuilders;
     }
 
+    /**
+     * Sets the 'useJakartaValidation' property of this class
+     *
+     * @param useJakartaValidation Whether to use annotations from {@code jakarta.validation} package instead of {@code javax.validation} package
+     *                             when adding <a href="http://jcp.org/en/jsr/detail?id=303">JSR-303</a> annotations to generated Java types.
+     */
+    public void setUseJakartaValidation(boolean useJakartaValidation) {
+        this.useJakartaValidation = useJakartaValidation;
+    }
+
     public void setFormatTypeMapping(Map<String, String> formatTypeMapping) {
         this.formatTypeMapping = formatTypeMapping;
     }
@@ -1314,7 +1325,14 @@ public class Jsonschema2PojoTask extends Task implements GenerationConfig {
     public boolean isIncludeConstructorPropertiesAnnotation() {
         return includeConstructorPropertiesAnnotation;
     }
-    
+
+    @Override
+    public boolean isIncludeGeneratedAnnotation() {
+        return includeGeneratedAnnotation;
+    }
+
     @Override
-    public boolean isIncludeGeneratedAnnotation() { return includeGeneratedAnnotation; }
+    public boolean isUseJakartaValidation() {
+        return useJakartaValidation;
+    }
 }
diff --git a/jsonschema2pojo-ant/src/site/Jsonschema2PojoTask.html b/jsonschema2pojo-ant/src/site/Jsonschema2PojoTask.html
index 6dab8f41..62deecb7 100644
--- a/jsonschema2pojo-ant/src/site/Jsonschema2PojoTask.html
+++ b/jsonschema2pojo-ant/src/site/Jsonschema2PojoTask.html
@@ -290,7 +290,7 @@
     <td align="center" valign="top">No (default <code>true</code>)</td>
   </tr>
   <tr>
-    <td valign="top">includeJsr303Annotations</td>
+    <td valign="top"><a id="includeJsr303Annotations"></a>includeJsr303Annotations</td>
     <td valign="top">Whether to include <a
         href="http://jcp.org/en/jsr/detail?id=303">JSR-303/349</a> annotations
       (for schema rules like minimum, maximum, etc) in generated Java types.
@@ -619,6 +619,15 @@
     <td valign="top">Include <code>@javax.annotation.Generated</code> annotation to generated types</td>
     <td align="center" valign="top">No (default <code>true</code>)</td>
   </tr>
+  <tr>
+      <td valign="top">useJakartaValidation</td>
+      <td valign="top">Whether to use annotations from <code>jakarta.validation</code> package instead of <code>javax.validation</code>
+          package when adding <a href="http://jcp.org/en/jsr/detail?id=303">JSR-303</a> annotations to generated Java types.<br/>
+          This configuration option works in collaboration with the <a href="#includeJsr303Annotations">includeJsr303Annotations</a>
+          configuration option and will have no effect if latter is set to <code>false</code>
+      </td>
+      <td align="center" valign="top">No (default <code>false</code>)</td>
+  </tr>
 </table>
 <h3>Examples</h3>
 <pre>
diff --git a/jsonschema2pojo-cli/src/main/java/org/jsonschema2pojo/cli/Arguments.java b/jsonschema2pojo-cli/src/main/java/org/jsonschema2pojo/cli/Arguments.java
index 5a08a6ba..d7a2891b 100644
--- a/jsonschema2pojo-cli/src/main/java/org/jsonschema2pojo/cli/Arguments.java
+++ b/jsonschema2pojo-cli/src/main/java/org/jsonschema2pojo/cli/Arguments.java
@@ -246,6 +246,9 @@ public class Arguments implements GenerationConfig {
     @Parameter(names = {"--omit-generated-annotation"}, description = "Omit @Generated annotation on generated types")
     private boolean omitGeneratedAnnotation = false;
 
+    @Parameter(names = { "--useJakartaValidation" }, description = "Whether to use annotations from jakarta.validation package instead of javax.validation package when adding JSR-303/349 annotations to generated Java types")
+    private boolean useJakartaValidation = false;
+
     private static final int EXIT_OKAY = 0;
     private static final int EXIT_ERROR = 1;
 
@@ -601,7 +604,14 @@ public class Arguments implements GenerationConfig {
                 .stream()
                 .collect(Collectors.toMap(m -> m.split(":")[0], m -> m.split(":")[1]));
     }
-    
+
     @Override
-    public boolean isIncludeGeneratedAnnotation() { return !omitGeneratedAnnotation; }
+    public boolean isIncludeGeneratedAnnotation() {
+        return !omitGeneratedAnnotation;
+    }
+
+    @Override
+    public boolean isUseJakartaValidation() {
+        return useJakartaValidation;
+    }
 }
diff --git a/jsonschema2pojo-core/pom.xml b/jsonschema2pojo-core/pom.xml
index dde8580d..101e50f2 100644
--- a/jsonschema2pojo-core/pom.xml
+++ b/jsonschema2pojo-core/pom.xml
@@ -49,6 +49,10 @@
             <groupId>javax.validation</groupId>
             <artifactId>validation-api</artifactId>
         </dependency>
+        <dependency>
+            <groupId>jakarta.validation</groupId>
+            <artifactId>jakarta.validation-api</artifactId>
+        </dependency>
         <dependency>
             <groupId>joda-time</groupId>
             <artifactId>joda-time</artifactId>
diff --git a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/DefaultGenerationConfig.java b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/DefaultGenerationConfig.java
index 25718324..e9a453ce 100644
--- a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/DefaultGenerationConfig.java
+++ b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/DefaultGenerationConfig.java
@@ -484,6 +484,14 @@ public class DefaultGenerationConfig implements GenerationConfig {
      */
     @Override
     public boolean isIncludeGeneratedAnnotation() {
-    	return true;
+        return true;
+    }
+
+    /**
+     * @return {@code false}
+     */
+    @Override
+    public boolean isUseJakartaValidation() {
+        return false;
     }
 }
diff --git a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/GenerationConfig.java b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/GenerationConfig.java
index 629f82df..35f24e9b 100644
--- a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/GenerationConfig.java
+++ b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/GenerationConfig.java
@@ -610,11 +610,20 @@ public interface GenerationConfig {
   default boolean isUseInnerClassBuilders() {
     return false;
   }
-  
+
   /**
    * Whether to mark generated classes with the annotation <code>javax.annotation.@Generated</code>
    *
    */
   boolean isIncludeGeneratedAnnotation();
-  
-}
+
+  /**
+   * Gets the 'useJakartaValidation' configuration option.
+   * This property works in collaboration with the {@link #isIncludeJsr303Annotations()} configuration option.
+   * If the {@link #isIncludeJsr303Annotations()} returns {@code false}, then this configuration option will not affect anything.
+   *
+   * @return Whether to use <a href="http://jcp.org/en/jsr/detail?id=303">JSR-303</a> annotations from {@code jakarta.validation} package instead of {@code javax.validation} package when adding JSR-303 annotations to generated Java types
+   */
+  boolean isUseJakartaValidation();
+
+}
\ No newline at end of file
diff --git a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/DigitsRule.java b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/DigitsRule.java
index d05b1f7a..6a5d9c03 100644
--- a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/DigitsRule.java
+++ b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/DigitsRule.java
@@ -16,7 +16,7 @@
 
 package org.jsonschema2pojo.rules;
 
-import javax.validation.constraints.Digits;
+import java.lang.annotation.Annotation;
 
 import org.jsonschema2pojo.Schema;
 
@@ -24,6 +24,8 @@ import com.fasterxml.jackson.databind.JsonNode;
 import com.sun.codemodel.JAnnotationUse;
 import com.sun.codemodel.JFieldVar;
 
+import jakarta.validation.constraints.Digits;
+
 public class DigitsRule implements Rule<JFieldVar, JFieldVar> {
 
     private final RuleFactory ruleFactory;
@@ -39,7 +41,11 @@ public class DigitsRule implements Rule<JFieldVar, JFieldVar> {
             && node.has("integerDigits") && node.has("fractionalDigits")
             && isApplicableType(field)) {
 
-            JAnnotationUse annotation = field.annotate(Digits.class);
+            final Class<? extends Annotation> digitsClass
+                    = ruleFactory.getGenerationConfig().isUseJakartaValidation()
+                    ? Digits.class
+                    : javax.validation.constraints.Digits.class;
+            JAnnotationUse annotation = field.annotate(digitsClass);
 
             annotation.param("integer", node.get("integerDigits").asInt());
             annotation.param("fraction", node.get("fractionalDigits").asInt());
diff --git a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/MinItemsMaxItemsRule.java b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/MinItemsMaxItemsRule.java
index f3564d57..b32f5e50 100644
--- a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/MinItemsMaxItemsRule.java
+++ b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/MinItemsMaxItemsRule.java
@@ -16,18 +16,19 @@
 
 package org.jsonschema2pojo.rules;
 
+import java.lang.annotation.Annotation;
 import java.lang.reflect.Array;
 import java.util.Collection;
 import java.util.Map;
 
-import javax.validation.constraints.Size;
-
 import org.jsonschema2pojo.Schema;
 
 import com.fasterxml.jackson.databind.JsonNode;
 import com.sun.codemodel.JAnnotationUse;
 import com.sun.codemodel.JFieldVar;
 
+import jakarta.validation.constraints.Size;
+
 public class MinItemsMaxItemsRule implements Rule<JFieldVar, JFieldVar> {
 
     private final RuleFactory ruleFactory;
@@ -43,7 +44,11 @@ public class MinItemsMaxItemsRule implements Rule<JFieldVar, JFieldVar> {
                 && (node.has("minItems") || node.has("maxItems"))
                 && isApplicableType(field)) {
 
-            JAnnotationUse annotation = field.annotate(Size.class);
+            final Class<? extends Annotation> sizeClass
+                    = ruleFactory.getGenerationConfig().isUseJakartaValidation()
+                    ? Size.class
+                    : javax.validation.constraints.Size.class;
+            JAnnotationUse annotation = field.annotate(sizeClass);
 
             if (node.has("minItems")) {
                 annotation.param("min", node.get("minItems").asInt());
diff --git a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/MinLengthMaxLengthRule.java b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/MinLengthMaxLengthRule.java
index dce75a29..47cdb8fe 100644
--- a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/MinLengthMaxLengthRule.java
+++ b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/MinLengthMaxLengthRule.java
@@ -16,18 +16,19 @@
 
 package org.jsonschema2pojo.rules;
 
+import java.lang.annotation.Annotation;
 import java.lang.reflect.Array;
 import java.util.Collection;
 import java.util.Map;
 
-import javax.validation.constraints.Size;
-
 import org.jsonschema2pojo.Schema;
 
 import com.fasterxml.jackson.databind.JsonNode;
 import com.sun.codemodel.JAnnotationUse;
 import com.sun.codemodel.JFieldVar;
 
+import jakarta.validation.constraints.Size;
+
 public class MinLengthMaxLengthRule implements Rule<JFieldVar, JFieldVar> {
     
     private final RuleFactory ruleFactory;
@@ -43,7 +44,11 @@ public class MinLengthMaxLengthRule implements Rule<JFieldVar, JFieldVar> {
                 && (node.has("minLength") || node.has("maxLength"))
                 && isApplicableType(field)) {
 
-            JAnnotationUse annotation = field.annotate(Size.class);
+            final Class<? extends Annotation> sizeClass
+                    = ruleFactory.getGenerationConfig().isUseJakartaValidation()
+                    ? Size.class
+                    : javax.validation.constraints.Size.class;
+            JAnnotationUse annotation = field.annotate(sizeClass);
 
             if (node.has("minLength")) {
                 annotation.param("min", node.get("minLength").asInt());
diff --git a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/MinimumMaximumRule.java b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/MinimumMaximumRule.java
index e859e414..55f56bee 100644
--- a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/MinimumMaximumRule.java
+++ b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/MinimumMaximumRule.java
@@ -16,8 +16,7 @@
 
 package org.jsonschema2pojo.rules;
 
-import javax.validation.constraints.DecimalMax;
-import javax.validation.constraints.DecimalMin;
+import java.lang.annotation.Annotation;
 
 import org.jsonschema2pojo.Schema;
 
@@ -25,6 +24,9 @@ import com.fasterxml.jackson.databind.JsonNode;
 import com.sun.codemodel.JAnnotationUse;
 import com.sun.codemodel.JFieldVar;
 
+import jakarta.validation.constraints.DecimalMax;
+import jakarta.validation.constraints.DecimalMin;
+
 public class MinimumMaximumRule implements Rule<JFieldVar, JFieldVar> {
 
     private final RuleFactory ruleFactory;
@@ -39,12 +41,20 @@ public class MinimumMaximumRule implements Rule<JFieldVar, JFieldVar> {
         if (ruleFactory.getGenerationConfig().isIncludeJsr303Annotations() && isApplicableType(field)) {
 
             if (node.has("minimum")) {
-                JAnnotationUse annotation = field.annotate(DecimalMin.class);
+                final Class<? extends Annotation> decimalMinClass
+                        = ruleFactory.getGenerationConfig().isUseJakartaValidation()
+                        ? DecimalMin.class
+                        : javax.validation.constraints.DecimalMin.class;
+                JAnnotationUse annotation = field.annotate(decimalMinClass);
                 annotation.param("value", node.get("minimum").asText());
             }
 
             if (node.has("maximum")) {
-                JAnnotationUse annotation = field.annotate(DecimalMax.class);
+                final Class<? extends Annotation> decimalMaxClass
+                        = ruleFactory.getGenerationConfig().isUseJakartaValidation()
+                        ? DecimalMax.class
+                        : javax.validation.constraints.DecimalMax.class;
+                JAnnotationUse annotation = field.annotate(decimalMaxClass);
                 annotation.param("value", node.get("maximum").asText());
             }
 
diff --git a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/PatternRule.java b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/PatternRule.java
index 4f0961da..1349b2f7 100644
--- a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/PatternRule.java
+++ b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/PatternRule.java
@@ -16,7 +16,7 @@
 
 package org.jsonschema2pojo.rules;
 
-import javax.validation.constraints.Pattern;
+import java.lang.annotation.Annotation;
 
 import org.jsonschema2pojo.Schema;
 
@@ -24,6 +24,8 @@ import com.fasterxml.jackson.databind.JsonNode;
 import com.sun.codemodel.JAnnotationUse;
 import com.sun.codemodel.JFieldVar;
 
+import jakarta.validation.constraints.Pattern;
+
 public class PatternRule implements Rule<JFieldVar, JFieldVar> {
 
     private RuleFactory ruleFactory;
@@ -36,7 +38,11 @@ public class PatternRule implements Rule<JFieldVar, JFieldVar> {
     public JFieldVar apply(String nodeName, JsonNode node, JsonNode parent, JFieldVar field, Schema currentSchema) {
 
         if (ruleFactory.getGenerationConfig().isIncludeJsr303Annotations() && isApplicableType(field)) {
-            JAnnotationUse annotation = field.annotate(Pattern.class);
+            final Class<? extends Annotation> patternClass
+                    = ruleFactory.getGenerationConfig().isUseJakartaValidation()
+                    ? Pattern.class
+                    : javax.validation.constraints.Pattern.class;
+            JAnnotationUse annotation = field.annotate(patternClass);
             annotation.param("regexp", node.asText());
         }
 
diff --git a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/RequiredArrayRule.java b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/RequiredArrayRule.java
index 6f54d37f..364e6eab 100644
--- a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/RequiredArrayRule.java
+++ b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/RequiredArrayRule.java
@@ -16,12 +16,12 @@
 
 package org.jsonschema2pojo.rules;
 
+import java.lang.annotation.Annotation;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 
 import javax.annotation.Nonnull;
-import javax.validation.constraints.NotNull;
 
 import org.jsonschema2pojo.Schema;
 
@@ -33,6 +33,8 @@ import com.sun.codemodel.JFieldVar;
 import com.sun.codemodel.JMethod;
 import com.sun.codemodel.JType;
 
+import jakarta.validation.constraints.NotNull;
+
 /**
  * Applies the "required" JSON schema rule.
  *
@@ -103,7 +105,11 @@ public class RequiredArrayRule implements Rule<JDefinedClass, JDefinedClass> {
     }
 
     private void addNotNullAnnotation(JFieldVar field) {
-        field.annotate(NotNull.class);
+        final Class<? extends Annotation> notNullClass
+                = ruleFactory.getGenerationConfig().isUseJakartaValidation()
+                ? NotNull.class
+                : javax.validation.constraints.NotNull.class;
+        field.annotate(notNullClass);
     }
 
     private void addNonnullAnnotation(JFieldVar field) {
diff --git a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/RequiredRule.java b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/RequiredRule.java
index 92a88d9b..54e6c87c 100644
--- a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/RequiredRule.java
+++ b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/RequiredRule.java
@@ -16,9 +16,10 @@
 
 package org.jsonschema2pojo.rules;
 
+import java.lang.annotation.Annotation;
+
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
-import javax.validation.constraints.NotNull;
 
 import org.jsonschema2pojo.Schema;
 
@@ -26,6 +27,8 @@ import com.fasterxml.jackson.databind.JsonNode;
 import com.sun.codemodel.JDocCommentable;
 import com.sun.codemodel.JFieldVar;
 
+import jakarta.validation.constraints.NotNull;
+
 /**
  * Applies the "required" schema rule.
  *
@@ -68,7 +71,11 @@ public class RequiredRule implements Rule<JDocCommentable, JDocCommentable> {
 
             if (ruleFactory.getGenerationConfig().isIncludeJsr303Annotations()
                     && generatableType instanceof JFieldVar) {
-                ((JFieldVar) generatableType).annotate(NotNull.class);
+                final Class<? extends Annotation> notNullClass
+                        = ruleFactory.getGenerationConfig().isUseJakartaValidation()
+                        ? NotNull.class
+                        : javax.validation.constraints.NotNull.class;
+                ((JFieldVar) generatableType).annotate(notNullClass);
             }
 
             if (ruleFactory.getGenerationConfig().isIncludeJsr305Annotations()
diff --git a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/ValidRule.java b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/ValidRule.java
index f0a3f519..657b607b 100644
--- a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/ValidRule.java
+++ b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/ValidRule.java
@@ -16,13 +16,15 @@
 
 package org.jsonschema2pojo.rules;
 
-import javax.validation.Valid;
+import java.lang.annotation.Annotation;
 
 import org.jsonschema2pojo.Schema;
 
 import com.fasterxml.jackson.databind.JsonNode;
 import com.sun.codemodel.JFieldVar;
 
+import jakarta.validation.Valid;
+
 public class ValidRule implements Rule<JFieldVar, JFieldVar> {
     
     private final RuleFactory ruleFactory;
@@ -35,7 +37,11 @@ public class ValidRule implements Rule<JFieldVar, JFieldVar> {
     public JFieldVar apply(String nodeName, JsonNode node, JsonNode parent, JFieldVar field, Schema currentSchema) {
         
         if (ruleFactory.getGenerationConfig().isIncludeJsr303Annotations()) {
-            field.annotate(Valid.class);
+            final Class<? extends Annotation> validClass
+                    = ruleFactory.getGenerationConfig().isUseJakartaValidation()
+                    ? Valid.class
+                    : javax.validation.Valid.class;
+            field.annotate(validClass);
         }
         
         return field;
diff --git a/jsonschema2pojo-gradle-plugin/README.md b/jsonschema2pojo-gradle-plugin/README.md
index 3d95dfb6..b2a48ef4 100644
--- a/jsonschema2pojo-gradle-plugin/README.md
+++ b/jsonschema2pojo-gradle-plugin/README.md
@@ -36,6 +36,7 @@ repositories {
 dependencies {
   // Required if generating JSR-303 annotations
   implementation 'javax.validation:validation-api:1.1.0.CR2'
+  implementation 'jakarta.validation:jakarta.validation-api:3.0.0'
   // Required if generating Jackson 2 annotations
   implementation 'com.fasterxml.jackson.core:jackson-databind:2.12.1'
   // Required if generating JodaTime data types
@@ -289,6 +290,9 @@ jsonSchema2Pojo {
   // order), SourceSortOrder.FILES_FIRST or SourceSortOrder.SUBDIRS_FIRST
   sourceSortOrder = SourceSortOrder.OS
 
+  // Whether to use annotations from jakarta.validation package instead of javax.validation package
+  // when adding JSR-303 annotations to generated Java types
+  useJakartaValidation = false
 }
 ```
 
diff --git a/jsonschema2pojo-gradle-plugin/example/android/app/build.gradle b/jsonschema2pojo-gradle-plugin/example/android/app/build.gradle
index ffb9a97c..463f9c31 100644
--- a/jsonschema2pojo-gradle-plugin/example/android/app/build.gradle
+++ b/jsonschema2pojo-gradle-plugin/example/android/app/build.gradle
@@ -35,6 +35,7 @@ dependencies {
     implementation 'com.squareup.moshi:moshi:1.12.0'
     // Required if generating JSR-303 annotations
     implementation 'javax.validation:validation-api:2.0.1.Final'
+    implementation 'jakarta.validation:jakarta.validation-api:3.0.0'
     // Required if generating Jackson 2 annotations
     implementation 'com.fasterxml.jackson.core:jackson-databind:2.12.3'
 }
diff --git a/jsonschema2pojo-gradle-plugin/example/android/lib/build.gradle b/jsonschema2pojo-gradle-plugin/example/android/lib/build.gradle
index 5e171745..7d369a49 100644
--- a/jsonschema2pojo-gradle-plugin/example/android/lib/build.gradle
+++ b/jsonschema2pojo-gradle-plugin/example/android/lib/build.gradle
@@ -31,6 +31,7 @@ dependencies {
     implementation 'com.squareup.moshi:moshi:1.12.0'
     // Required if generating JSR-303 annotations
     implementation 'javax.validation:validation-api:2.0.1.Final'
+    implementation 'jakarta.validation:jakarta.validation-api:3.0.0'
     // Required if generating Jackson 2 annotations
     implementation 'com.fasterxml.jackson.core:jackson-databind:2.12.3'
 }
diff --git a/jsonschema2pojo-gradle-plugin/example/java/build.gradle b/jsonschema2pojo-gradle-plugin/example/java/build.gradle
index 48e32688..82af2059 100644
--- a/jsonschema2pojo-gradle-plugin/example/java/build.gradle
+++ b/jsonschema2pojo-gradle-plugin/example/java/build.gradle
@@ -21,6 +21,7 @@ repositories {
 
 dependencies {
   implementation 'javax.validation:validation-api:1.1.0.CR2'
+  implementation 'jakarta.validation:jakarta.validation-api:3.0.0'
   implementation 'com.fasterxml.jackson.core:jackson-databind:2.12.1'
 
   // see src/main/resources/json/external_dependencies.json
diff --git a/jsonschema2pojo-gradle-plugin/src/main/groovy/org/jsonschema2pojo/gradle/JsonSchemaExtension.groovy b/jsonschema2pojo-gradle-plugin/src/main/groovy/org/jsonschema2pojo/gradle/JsonSchemaExtension.groovy
index eb8348db..324f3cad 100644
--- a/jsonschema2pojo-gradle-plugin/src/main/groovy/org/jsonschema2pojo/gradle/JsonSchemaExtension.groovy
+++ b/jsonschema2pojo-gradle-plugin/src/main/groovy/org/jsonschema2pojo/gradle/JsonSchemaExtension.groovy
@@ -96,6 +96,7 @@ public class JsonSchemaExtension implements GenerationConfig {
   SourceSortOrder sourceSortOrder
   Map<String, String> formatTypeMapping
   boolean includeGeneratedAnnotation
+  boolean useJakartaValidation
 
   public JsonSchemaExtension() {
     // See DefaultGenerationConfig
@@ -156,6 +157,7 @@ public class JsonSchemaExtension implements GenerationConfig {
     sourceSortOrder = SourceSortOrder.OS
     formatTypeMapping = Collections.emptyMap()
     includeGeneratedAnnotation = true
+    useJakartaValidation = false
   }
 
   @Override
@@ -285,9 +287,10 @@ public class JsonSchemaExtension implements GenerationConfig {
        |useInnerClassBuilders = ${useInnerClassBuilders}
        |includeConstructorPropertiesAnnotation = ${includeConstructorPropertiesAnnotation}
        |includeGeneratedAnnotation = ${includeGeneratedAnnotation}
+       |useJakartaValidation = ${useJakartaValidation}
      """.stripMargin()
   }
-  
+
   public boolean isFormatDateTimes() {
     return formatDateTimes
   }
diff --git a/jsonschema2pojo-maven-plugin/src/main/java/org/jsonschema2pojo/maven/Jsonschema2PojoMojo.java b/jsonschema2pojo-maven-plugin/src/main/java/org/jsonschema2pojo/maven/Jsonschema2PojoMojo.java
index 3746541c..9c05bb1e 100644
--- a/jsonschema2pojo-maven-plugin/src/main/java/org/jsonschema2pojo/maven/Jsonschema2PojoMojo.java
+++ b/jsonschema2pojo-maven-plugin/src/main/java/org/jsonschema2pojo/maven/Jsonschema2PojoMojo.java
@@ -800,10 +800,21 @@ public class Jsonschema2PojoMojo extends AbstractMojo implements GenerationConfi
      * on generated types.
      *
      * @parameter property="jsonschema2pojo.includeGeneratedAnnotation"
-     *            default-value="true"
+     * default-value="true"
      */
     private boolean includeGeneratedAnnotation = true;
 
+    /**
+     * Whether to use annotations from {@code jakarta.validation} package instead of {@code javax.validation} package
+     * when adding <a href="http://jcp.org/en/jsr/detail?id=303">JSR-303</a> annotations to generated Java types.
+     * This property works in collaboration with the {@link #isIncludeJsr303Annotations()} configuration option.
+     * If the {@link #isIncludeJsr303Annotations()} returns {@code false}, then this configuration option will not affect anything.
+     *
+     * @parameter property="jsonschema2pojo.useJakartaValidation"
+     * default-value="false"
+     */
+    private boolean useJakartaValidation = false;
+
     /**
      * Executes the plugin, to read the given source and behavioural properties
      * and generate POJOs. The current implementation acts as a wrapper around
@@ -1255,4 +1266,9 @@ public class Jsonschema2PojoMojo extends AbstractMojo implements GenerationConfi
     public boolean isIncludeGeneratedAnnotation() {
         return includeGeneratedAnnotation;
     }
+
+    @Override
+    public boolean isUseJakartaValidation() {
+        return useJakartaValidation;
+    }
 }
diff --git a/pom.xml b/pom.xml
index 13c125eb..59a75974 100644
--- a/pom.xml
+++ b/pom.xml
@@ -375,6 +375,11 @@
                 <artifactId>validation-api</artifactId>
                 <version>1.0.0.GA</version>
             </dependency>
+            <dependency>
+                <groupId>jakarta.validation</groupId>
+                <artifactId>jakarta.validation-api</artifactId>
+                <version>3.0.0</version>
+            </dependency>
             <dependency>
                 <groupId>joda-time</groupId>
                 <artifactId>joda-time</artifactId>
@@ -445,9 +450,15 @@
                 <scope>test</scope>
             </dependency>
             <dependency>
-                <groupId>org.hibernate</groupId>
+                <groupId>org.hibernate.validator</groupId>
                 <artifactId>hibernate-validator</artifactId>
-                <version>4.3.0.Final</version>
+                <version>7.0.1.Final</version>
+                <scope>test</scope>
+            </dependency>
+            <dependency>
+                <groupId>org.glassfish</groupId>
+                <artifactId>jakarta.el</artifactId>
+                <version>4.0.0</version>
                 <scope>test</scope>
             </dependency>
             <dependency>


Test patch:
diff --git a/jsonschema2pojo-core/src/test/java/org/jsonschema2pojo/rules/DigitsRuleTest.java b/jsonschema2pojo-core/src/test/java/org/jsonschema2pojo/rules/DigitsRuleTest.java
index c4d56bee..044b1e35 100644
--- a/jsonschema2pojo-core/src/test/java/org/jsonschema2pojo/rules/DigitsRuleTest.java
+++ b/jsonschema2pojo-core/src/test/java/org/jsonschema2pojo/rules/DigitsRuleTest.java
@@ -21,14 +21,13 @@ import static org.junit.Assert.*;
 import static org.mockito.ArgumentMatchers.*;
 import static org.mockito.Mockito.*;
 
+import java.lang.annotation.Annotation;
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.util.Collection;
 import java.util.Random;
-
-import javax.validation.constraints.DecimalMin;
-import javax.validation.constraints.Digits;
-import javax.validation.constraints.Size;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import org.jsonschema2pojo.GenerationConfig;
 import org.jsonschema2pojo.NoopAnnotator;
@@ -45,6 +44,10 @@ import com.fasterxml.jackson.databind.JsonNode;
 import com.sun.codemodel.JAnnotationUse;
 import com.sun.codemodel.JFieldVar;
 
+import jakarta.validation.constraints.DecimalMin;
+import jakarta.validation.constraints.Digits;
+import jakarta.validation.constraints.Size;
+
 /**
  * Tests {@link DigitsRuleTest}
  */
@@ -54,6 +57,10 @@ public class DigitsRuleTest {
     private final boolean isApplicable;
     private DigitsRule rule;
     private Class<?> fieldClass;
+    private final boolean useJakartaValidation;
+    private final Class<? extends Annotation> digitsClass;
+    private final Class<? extends Annotation> sizeClass;
+    private final Class<? extends Annotation> decimalMinClass;
     @Mock
     private GenerationConfig config;
     @Mock
@@ -79,19 +86,31 @@ public class DigitsRuleTest {
                 { true, Long.class },
                 { false, Float.class },
                 { false, Double.class },
-        });
+        }).stream()
+                .flatMap(o -> Stream.of(true, false).map(b -> Stream.concat(stream(o), Stream.of(b)).toArray()))
+                .collect(Collectors.toList());
     }
 
-
-    public DigitsRuleTest(boolean isApplicable, Class<?> fieldClass) {
+    public DigitsRuleTest(boolean isApplicable, Class<?> fieldClass, boolean useJakartaValidation) {
         this.isApplicable = isApplicable;
         this.fieldClass = fieldClass;
+        this.useJakartaValidation = useJakartaValidation;
+        if (useJakartaValidation) {
+            digitsClass = Digits.class;
+            sizeClass = Size.class;
+            decimalMinClass = DecimalMin.class;
+        } else {
+            digitsClass = javax.validation.constraints.Digits.class;
+            sizeClass = javax.validation.constraints.Size.class;
+            decimalMinClass = javax.validation.constraints.DecimalMin.class;
+        }
     }
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         rule = new DigitsRule(new RuleFactory(config, new NoopAnnotator(), new SchemaStore()));
+        when(config.isUseJakartaValidation()).thenReturn(useJakartaValidation);
     }
 
     @Test
@@ -104,7 +123,7 @@ public class DigitsRuleTest {
         when(subNodeFractional.asInt()).thenReturn(fractionalValue);
         when(node.get("integerDigits")).thenReturn(subNodeInteger);
         when(node.get("fractionalDigits")).thenReturn(subNodeFractional);
-        when(fieldVar.annotate(Digits.class)).thenReturn(annotation);
+        when(fieldVar.annotate(digitsClass)).thenReturn(annotation);
         when(node.has("integerDigits")).thenReturn(true);
         when(node.has("fractionalDigits")).thenReturn(true);
         when(fieldVar.type().boxify().fullName()).thenReturn(fieldClass.getTypeName());
@@ -112,7 +131,7 @@ public class DigitsRuleTest {
         JFieldVar result = rule.apply("node", node, null, fieldVar, null);
         assertSame(fieldVar, result);
 
-        verify(fieldVar, times(isApplicable ? 1 : 0)).annotate(Digits.class);
+        verify(fieldVar, times(isApplicable ? 1 : 0)).annotate(digitsClass);
         verify(annotation, times(isApplicable ? 1 : 0)).param("integer", intValue);
         verify(annotation, times(isApplicable ? 1 : 0)).param("fraction", fractionalValue);
     }
@@ -127,7 +146,7 @@ public class DigitsRuleTest {
         JFieldVar result = rule.apply("node", node, null, fieldVar, null);
         assertSame(fieldVar, result);
 
-        verify(fieldVar, never()).annotate(Size.class);
+        verify(fieldVar, never()).annotate(sizeClass);
         verify(annotation, never()).param(anyString(), anyInt());
     }
 
@@ -137,7 +156,7 @@ public class DigitsRuleTest {
         JFieldVar result = rule.apply("node", node, null, fieldVar, null);
         assertSame(fieldVar, result);
 
-        verify(fieldVar, never()).annotate(DecimalMin.class);
+        verify(fieldVar, never()).annotate(decimalMinClass);
         verify(annotation, never()).param(anyString(), anyInt());
     }
 
diff --git a/jsonschema2pojo-core/src/test/java/org/jsonschema2pojo/rules/MinItemsMaxItemsRuleTest.java b/jsonschema2pojo-core/src/test/java/org/jsonschema2pojo/rules/MinItemsMaxItemsRuleTest.java
index f9e89bf5..d5abbac0 100644
--- a/jsonschema2pojo-core/src/test/java/org/jsonschema2pojo/rules/MinItemsMaxItemsRuleTest.java
+++ b/jsonschema2pojo-core/src/test/java/org/jsonschema2pojo/rules/MinItemsMaxItemsRuleTest.java
@@ -21,12 +21,13 @@ import static org.junit.Assert.*;
 import static org.mockito.ArgumentMatchers.*;
 import static org.mockito.Mockito.*;
 
+import java.lang.annotation.Annotation;
 import java.lang.reflect.Array;
 import java.util.Collection;
 import java.util.Map;
 import java.util.Random;
-
-import javax.validation.constraints.Size;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import org.jsonschema2pojo.GenerationConfig;
 import org.jsonschema2pojo.NoopAnnotator;
@@ -44,6 +45,8 @@ import com.fasterxml.jackson.databind.JsonNode;
 import com.sun.codemodel.JAnnotationUse;
 import com.sun.codemodel.JFieldVar;
 
+import jakarta.validation.constraints.Size;
+
 /**
  * Tests {@link MinItemsMaxItemsRuleTest}
  */
@@ -53,6 +56,8 @@ public class MinItemsMaxItemsRuleTest {
     private final boolean isApplicable;
     private MinItemsMaxItemsRule rule;
     private Class<?> fieldClass;
+    private final boolean useJakartaValidation;
+    private final Class<? extends Annotation> sizeClass;
     @Mock
     private GenerationConfig config;
     @Mock
@@ -77,19 +82,23 @@ public class MinItemsMaxItemsRuleTest {
                 { false, Long.class },
                 { false, Float.class },
                 { false, Double.class },
-        });
+        }).stream()
+                .flatMap(o -> Stream.of(true, false).map(b -> Stream.concat(stream(o), Stream.of(b)).toArray()))
+                .collect(Collectors.toList());
     }
 
-
-    public MinItemsMaxItemsRuleTest(boolean isApplicable, Class<?> fieldClass) {
+    public MinItemsMaxItemsRuleTest(boolean isApplicable, Class<?> fieldClass, boolean useJakartaValidation) {
         this.isApplicable = isApplicable;
         this.fieldClass = fieldClass;
+        this.useJakartaValidation = useJakartaValidation;
+        this.sizeClass = useJakartaValidation ? Size.class : javax.validation.constraints.Size.class;
     }
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         rule = new MinItemsMaxItemsRule(new RuleFactory(config, new NoopAnnotator(), new SchemaStore()));
+        when(config.isUseJakartaValidation()).thenReturn(useJakartaValidation);
     }
 
     @Test
@@ -98,14 +107,14 @@ public class MinItemsMaxItemsRuleTest {
         final int minValue = new Random().nextInt();
         when(subNode.asInt()).thenReturn(minValue);
         when(node.get("minItems")).thenReturn(subNode);
-        when(fieldVar.annotate(Size.class)).thenReturn(annotation);
+        when(fieldVar.annotate(sizeClass)).thenReturn(annotation);
         when(node.has("minItems")).thenReturn(true);
         when(fieldVar.type().boxify().fullName()).thenReturn(fieldClass.getTypeName());
 
         JFieldVar result = rule.apply("node", node, null, fieldVar, null);
         assertSame(fieldVar, result);
 
-        verify(fieldVar, times(isApplicable ? 1 : 0)).annotate(Size.class);
+        verify(fieldVar, times(isApplicable ? 1 : 0)).annotate(sizeClass);
         verify(annotation, times(isApplicable ? 1 : 0)).param("min", minValue);
         verify(annotation, never()).param(eq("max"), anyString());
     }
@@ -116,14 +125,14 @@ public class MinItemsMaxItemsRuleTest {
         final int maxValue = new Random().nextInt();
         when(subNode.asInt()).thenReturn(maxValue);
         when(node.get("maxItems")).thenReturn(subNode);
-        when(fieldVar.annotate(Size.class)).thenReturn(annotation);
+        when(fieldVar.annotate(sizeClass)).thenReturn(annotation);
         when(node.has("maxItems")).thenReturn(true);
         when(fieldVar.type().boxify().fullName()).thenReturn(fieldClass.getTypeName());
 
         JFieldVar result = rule.apply("node", node, null, fieldVar, null);
         assertSame(fieldVar, result);
 
-        verify(fieldVar, times(isApplicable ? 1 : 0)).annotate(Size.class);
+        verify(fieldVar, times(isApplicable ? 1 : 0)).annotate(sizeClass);
         verify(annotation, times(isApplicable ? 1 : 0)).param("max", maxValue);
         verify(annotation, never()).param(eq("min"), anyInt());
     }
@@ -138,7 +147,7 @@ public class MinItemsMaxItemsRuleTest {
         when(maxSubNode.asInt()).thenReturn(maxValue);
         when(node.get("minItems")).thenReturn(subNode);
         when(node.get("maxItems")).thenReturn(maxSubNode);
-        when(fieldVar.annotate(Size.class)).thenReturn(annotation);
+        when(fieldVar.annotate(sizeClass)).thenReturn(annotation);
         when(node.has("minItems")).thenReturn(true);
         when(node.has("maxItems")).thenReturn(true);
         when(fieldVar.type().boxify().fullName()).thenReturn(fieldClass.getTypeName());
@@ -146,7 +155,7 @@ public class MinItemsMaxItemsRuleTest {
         JFieldVar result = rule.apply("node", node, null, fieldVar, null);
         assertSame(fieldVar, result);
 
-        verify(fieldVar, times(isApplicable ? 1 : 0)).annotate(Size.class);
+        verify(fieldVar, times(isApplicable ? 1 : 0)).annotate(sizeClass);
         verify(annotation, times(isApplicable ? 1 : 0)).param("min", minValue);
         verify(annotation, times(isApplicable ? 1 : 0)).param("max", maxValue);
     }
@@ -161,7 +170,7 @@ public class MinItemsMaxItemsRuleTest {
         when(maxSubNode.asInt()).thenReturn(maxValue);
         when(node.get("minItems")).thenReturn(subNode);
         when(node.get("maxItems")).thenReturn(maxSubNode);
-        when(fieldVar.annotate(Size.class)).thenReturn(annotation);
+        when(fieldVar.annotate(sizeClass)).thenReturn(annotation);
         when(node.has("minItems")).thenReturn(true);
         when(node.has("maxItems")).thenReturn(true);
         when(fieldVar.type().boxify().fullName()).thenReturn(fieldClass.getTypeName() + "<String>");
@@ -169,7 +178,7 @@ public class MinItemsMaxItemsRuleTest {
         JFieldVar result = rule.apply("node", node, null, fieldVar, null);
         assertSame(fieldVar, result);
 
-        verify(fieldVar, times(isApplicable ? 1 : 0)).annotate(Size.class);
+        verify(fieldVar, times(isApplicable ? 1 : 0)).annotate(sizeClass);
         verify(annotation, times(isApplicable ? 1 : 0)).param("min", minValue);
         verify(annotation, times(isApplicable ? 1 : 0)).param("max", maxValue);
     }
@@ -184,7 +193,7 @@ public class MinItemsMaxItemsRuleTest {
         JFieldVar result = rule.apply("node", node, null, fieldVar, null);
         assertSame(fieldVar, result);
 
-        verify(fieldVar, never()).annotate(Size.class);
+        verify(fieldVar, never()).annotate(sizeClass);
         verify(annotation, never()).param(anyString(), anyInt());
     }
 
@@ -194,7 +203,7 @@ public class MinItemsMaxItemsRuleTest {
         JFieldVar result = rule.apply("node", node, null, fieldVar, null);
         assertSame(fieldVar, result);
 
-        verify(fieldVar, never()).annotate(Size.class);
+        verify(fieldVar, never()).annotate(sizeClass);
         verify(annotation, never()).param(anyString(), anyInt());
     }
 }
\ No newline at end of file
diff --git a/jsonschema2pojo-core/src/test/java/org/jsonschema2pojo/rules/MinLengthMaxLengthRuleTest.java b/jsonschema2pojo-core/src/test/java/org/jsonschema2pojo/rules/MinLengthMaxLengthRuleTest.java
index 903f4194..a721e13b 100644
--- a/jsonschema2pojo-core/src/test/java/org/jsonschema2pojo/rules/MinLengthMaxLengthRuleTest.java
+++ b/jsonschema2pojo-core/src/test/java/org/jsonschema2pojo/rules/MinLengthMaxLengthRuleTest.java
@@ -21,12 +21,13 @@ import static org.junit.Assert.*;
 import static org.mockito.ArgumentMatchers.*;
 import static org.mockito.Mockito.*;
 
+import java.lang.annotation.Annotation;
 import java.lang.reflect.Array;
 import java.util.Collection;
 import java.util.Map;
 import java.util.Random;
-
-import javax.validation.constraints.Size;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import org.jsonschema2pojo.GenerationConfig;
 import org.jsonschema2pojo.NoopAnnotator;
@@ -44,6 +45,8 @@ import com.fasterxml.jackson.databind.JsonNode;
 import com.sun.codemodel.JAnnotationUse;
 import com.sun.codemodel.JFieldVar;
 
+import jakarta.validation.constraints.Size;
+
 /**
  * Tests {@link MinLengthMaxLengthRuleTest}
  */
@@ -53,6 +56,8 @@ public class MinLengthMaxLengthRuleTest {
     private final boolean isApplicable;
     private MinLengthMaxLengthRule rule;
     private Class<?> fieldClass;
+    private final boolean useJakartaValidation;
+    private final Class<? extends Annotation> sizeClass;
     @Mock
     private GenerationConfig config;
     @Mock
@@ -77,19 +82,23 @@ public class MinLengthMaxLengthRuleTest {
                 { false, Long.class },
                 { false, Float.class },
                 { false, Double.class },
-        });
+        }).stream()
+                .flatMap(o -> Stream.of(true, false).map(b -> Stream.concat(stream(o), Stream.of(b)).toArray()))
+                .collect(Collectors.toList());
     }
 
-
-    public MinLengthMaxLengthRuleTest(boolean isApplicable, Class<?> fieldClass) {
+    public MinLengthMaxLengthRuleTest(boolean isApplicable, Class<?> fieldClass, boolean useJakartaValidation) {
         this.isApplicable = isApplicable;
         this.fieldClass = fieldClass;
+        this.useJakartaValidation = useJakartaValidation;
+        this.sizeClass = useJakartaValidation ? Size.class : javax.validation.constraints.Size.class;
     }
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         rule = new MinLengthMaxLengthRule(new RuleFactory(config, new NoopAnnotator(), new SchemaStore()));
+        when(config.isUseJakartaValidation()).thenReturn(useJakartaValidation);
     }
 
     @Test
@@ -98,14 +107,14 @@ public class MinLengthMaxLengthRuleTest {
         final int minValue = new Random().nextInt();
         when(subNode.asInt()).thenReturn(minValue);
         when(node.get("minLength")).thenReturn(subNode);
-        when(fieldVar.annotate(Size.class)).thenReturn(annotation);
+        when(fieldVar.annotate(sizeClass)).thenReturn(annotation);
         when(node.has("minLength")).thenReturn(true);
         when(fieldVar.type().boxify().fullName()).thenReturn(fieldClass.getTypeName());
 
         JFieldVar result = rule.apply("node", node, null, fieldVar, null);
         assertSame(fieldVar, result);
 
-        verify(fieldVar, times(isApplicable ? 1 : 0)).annotate(Size.class);
+        verify(fieldVar, times(isApplicable ? 1 : 0)).annotate(sizeClass);
         verify(annotation, times(isApplicable ? 1 : 0)).param("min", minValue);
         verify(annotation, never()).param(eq("max"), anyString());
     }
@@ -116,14 +125,14 @@ public class MinLengthMaxLengthRuleTest {
         final int maxValue = new Random().nextInt();
         when(subNode.asInt()).thenReturn(maxValue);
         when(node.get("maxLength")).thenReturn(subNode);
-        when(fieldVar.annotate(Size.class)).thenReturn(annotation);
+        when(fieldVar.annotate(sizeClass)).thenReturn(annotation);
         when(node.has("maxLength")).thenReturn(true);
         when(fieldVar.type().boxify().fullName()).thenReturn(fieldClass.getTypeName());
 
         JFieldVar result = rule.apply("node", node, null, fieldVar, null);
         assertSame(fieldVar, result);
 
-        verify(fieldVar, times(isApplicable ? 1 : 0)).annotate(Size.class);
+        verify(fieldVar, times(isApplicable ? 1 : 0)).annotate(sizeClass);
         verify(annotation, times(isApplicable ? 1 : 0)).param("max", maxValue);
         verify(annotation, never()).param(eq("min"), anyInt());
     }
@@ -138,7 +147,7 @@ public class MinLengthMaxLengthRuleTest {
         when(maxSubNode.asInt()).thenReturn(maxValue);
         when(node.get("minLength")).thenReturn(subNode);
         when(node.get("maxLength")).thenReturn(maxSubNode);
-        when(fieldVar.annotate(Size.class)).thenReturn(annotation);
+        when(fieldVar.annotate(sizeClass)).thenReturn(annotation);
         when(node.has("minLength")).thenReturn(true);
         when(node.has("maxLength")).thenReturn(true);
         when(fieldVar.type().boxify().fullName()).thenReturn(fieldClass.getTypeName());
@@ -146,7 +155,7 @@ public class MinLengthMaxLengthRuleTest {
         JFieldVar result = rule.apply("node", node, null, fieldVar, null);
         assertSame(fieldVar, result);
 
-        verify(fieldVar, times(isApplicable ? 1 : 0)).annotate(Size.class);
+        verify(fieldVar, times(isApplicable ? 1 : 0)).annotate(sizeClass);
         verify(annotation, times(isApplicable ? 1 : 0)).param("min", minValue);
         verify(annotation, times(isApplicable ? 1 : 0)).param("max", maxValue);
     }
@@ -161,7 +170,7 @@ public class MinLengthMaxLengthRuleTest {
         when(maxSubNode.asInt()).thenReturn(maxValue);
         when(node.get("minLength")).thenReturn(subNode);
         when(node.get("maxLength")).thenReturn(maxSubNode);
-        when(fieldVar.annotate(Size.class)).thenReturn(annotation);
+        when(fieldVar.annotate(sizeClass)).thenReturn(annotation);
         when(node.has("minLength")).thenReturn(true);
         when(node.has("maxLength")).thenReturn(true);
         when(fieldVar.type().boxify().fullName()).thenReturn(fieldClass.getTypeName() + "<String>");
@@ -169,7 +178,7 @@ public class MinLengthMaxLengthRuleTest {
         JFieldVar result = rule.apply("node", node, null, fieldVar, null);
         assertSame(fieldVar, result);
 
-        verify(fieldVar, times(isApplicable ? 1 : 0)).annotate(Size.class);
+        verify(fieldVar, times(isApplicable ? 1 : 0)).annotate(sizeClass);
         verify(annotation, times(isApplicable ? 1 : 0)).param("min", minValue);
         verify(annotation, times(isApplicable ? 1 : 0)).param("max", maxValue);
     }
@@ -184,7 +193,7 @@ public class MinLengthMaxLengthRuleTest {
         JFieldVar result = rule.apply("node", node, null, fieldVar, null);
         assertSame(fieldVar, result);
 
-        verify(fieldVar, never()).annotate(Size.class);
+        verify(fieldVar, never()).annotate(sizeClass);
         verify(annotation, never()).param(anyString(), anyInt());
     }
 
@@ -194,7 +203,7 @@ public class MinLengthMaxLengthRuleTest {
         JFieldVar result = rule.apply("node", node, null, fieldVar, null);
         assertSame(fieldVar, result);
 
-        verify(fieldVar, never()).annotate(Size.class);
+        verify(fieldVar, never()).annotate(sizeClass);
         verify(annotation, never()).param(anyString(), anyInt());
     }
 }
\ No newline at end of file
diff --git a/jsonschema2pojo-core/src/test/java/org/jsonschema2pojo/rules/MinimumMaximumRuleTest.java b/jsonschema2pojo-core/src/test/java/org/jsonschema2pojo/rules/MinimumMaximumRuleTest.java
index a241a9c2..1c9d7d4e 100644
--- a/jsonschema2pojo-core/src/test/java/org/jsonschema2pojo/rules/MinimumMaximumRuleTest.java
+++ b/jsonschema2pojo-core/src/test/java/org/jsonschema2pojo/rules/MinimumMaximumRuleTest.java
@@ -21,14 +21,13 @@ import static org.junit.Assert.*;
 import static org.mockito.ArgumentMatchers.*;
 import static org.mockito.Mockito.*;
 
+import java.lang.annotation.Annotation;
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.util.Collection;
 import java.util.Random;
-
-import javax.validation.constraints.DecimalMax;
-import javax.validation.constraints.DecimalMin;
-import javax.validation.constraints.Size;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import org.jsonschema2pojo.GenerationConfig;
 import org.jsonschema2pojo.NoopAnnotator;
@@ -46,6 +45,10 @@ import com.fasterxml.jackson.databind.JsonNode;
 import com.sun.codemodel.JAnnotationUse;
 import com.sun.codemodel.JFieldVar;
 
+import jakarta.validation.constraints.DecimalMax;
+import jakarta.validation.constraints.DecimalMin;
+import jakarta.validation.constraints.Size;
+
 /**
  * Tests {@link MinimumMaximumRuleTest}
  */
@@ -55,6 +58,10 @@ public class MinimumMaximumRuleTest {
     private final boolean isApplicable;
     private MinimumMaximumRule rule;
     private Class<?> fieldClass;
+    private final boolean useJakartaValidation;
+    private final Class<? extends Annotation> decimalMaxClass;
+    private final Class<? extends Annotation> decimalMinClass;
+    private final Class<? extends Annotation> sizeClass;
     @Mock
     private GenerationConfig config;
     @Mock
@@ -80,19 +87,31 @@ public class MinimumMaximumRuleTest {
                 { true, Long.class },
                 { false, Float.class },
                 { false, Double.class },
-        });
+        }).stream()
+                .flatMap(o -> Stream.of(true, false).map(b -> Stream.concat(stream(o), Stream.of(b)).toArray()))
+                .collect(Collectors.toList());
     }
 
-
-    public MinimumMaximumRuleTest(boolean isApplicable, Class<?> fieldClass) {
+    public MinimumMaximumRuleTest(boolean isApplicable, Class<?> fieldClass, boolean useJakartaValidation) {
         this.isApplicable = isApplicable;
         this.fieldClass = fieldClass;
+        this.useJakartaValidation = useJakartaValidation;
+        if (useJakartaValidation) {
+            decimalMaxClass = DecimalMax.class;
+            decimalMinClass = DecimalMin.class;
+            sizeClass = Size.class;
+        } else {
+            decimalMaxClass = javax.validation.constraints.DecimalMax.class;
+            decimalMinClass = javax.validation.constraints.DecimalMin.class;
+            sizeClass = javax.validation.constraints.Size.class;
+        }
     }
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         rule = new MinimumMaximumRule(new RuleFactory(config, new NoopAnnotator(), new SchemaStore()));
+        when(config.isUseJakartaValidation()).thenReturn(useJakartaValidation);
     }
 
     @Test
@@ -101,16 +120,16 @@ public class MinimumMaximumRuleTest {
         final String minValue = Integer.toString(new Random().nextInt());
         when(subNode.asText()).thenReturn(minValue);
         when(node.get("minimum")).thenReturn(subNode);
-        when(fieldVar.annotate(DecimalMin.class)).thenReturn(annotationMin);
+        when(fieldVar.annotate(decimalMinClass)).thenReturn(annotationMin);
         when(node.has("minimum")).thenReturn(true);
         when(fieldVar.type().boxify().fullName()).thenReturn(fieldClass.getTypeName());
 
         JFieldVar result = rule.apply("node", node, null, fieldVar, null);
         assertSame(fieldVar, result);
 
-        verify(fieldVar, times(isApplicable ? 1 : 0)).annotate(DecimalMin.class);
+        verify(fieldVar, times(isApplicable ? 1 : 0)).annotate(decimalMinClass);
         verify(annotationMin, times(isApplicable ? 1 : 0)).param("value", minValue);
-        verify(fieldVar, never()).annotate(DecimalMax.class);
+        verify(fieldVar, never()).annotate(decimalMaxClass);
         verify(annotationMax, never()).param(eq("value"), anyString());
     }
 
@@ -120,16 +139,16 @@ public class MinimumMaximumRuleTest {
         final String maxValue = Integer.toString(new Random().nextInt());
         when(subNode.asText()).thenReturn(maxValue);
         when(node.get("maximum")).thenReturn(subNode);
-        when(fieldVar.annotate(DecimalMax.class)).thenReturn(annotationMax);
+        when(fieldVar.annotate(decimalMaxClass)).thenReturn(annotationMax);
         when(node.has("maximum")).thenReturn(true);
         when(fieldVar.type().boxify().fullName()).thenReturn(fieldClass.getTypeName());
 
         JFieldVar result = rule.apply("node", node, null, fieldVar, null);
         assertSame(fieldVar, result);
 
-        verify(fieldVar, times(isApplicable ? 1 : 0)).annotate(DecimalMax.class);
+        verify(fieldVar, times(isApplicable ? 1 : 0)).annotate(decimalMaxClass);
         verify(annotationMax, times(isApplicable ? 1 : 0)).param("value", maxValue);
-        verify(fieldVar, never()).annotate(DecimalMin.class);
+        verify(fieldVar, never()).annotate(decimalMinClass);
         verify(annotationMin, never()).param(eq("value"), anyString());
     }
 
@@ -143,8 +162,8 @@ public class MinimumMaximumRuleTest {
         when(maxSubNode.asText()).thenReturn(maxValue);
         when(node.get("minimum")).thenReturn(subNode);
         when(node.get("maximum")).thenReturn(maxSubNode);
-        when(fieldVar.annotate(DecimalMin.class)).thenReturn(annotationMin);
-        when(fieldVar.annotate(DecimalMax.class)).thenReturn(annotationMax);
+        when(fieldVar.annotate(decimalMinClass)).thenReturn(annotationMin);
+        when(fieldVar.annotate(decimalMaxClass)).thenReturn(annotationMax);
         when(node.has("minimum")).thenReturn(true);
         when(node.has("maximum")).thenReturn(true);
         when(fieldVar.type().boxify().fullName()).thenReturn(fieldClass.getTypeName());
@@ -152,9 +171,9 @@ public class MinimumMaximumRuleTest {
         JFieldVar result = rule.apply("node", node, null, fieldVar, null);
         assertSame(fieldVar, result);
 
-        verify(fieldVar, times(isApplicable ? 1 : 0)).annotate(DecimalMin.class);
+        verify(fieldVar, times(isApplicable ? 1 : 0)).annotate(decimalMinClass);
         verify(annotationMin, times(isApplicable ? 1 : 0)).param("value", minValue);
-        verify(fieldVar, times(isApplicable ? 1 : 0)).annotate(DecimalMax.class);
+        verify(fieldVar, times(isApplicable ? 1 : 0)).annotate(decimalMaxClass);
         verify(annotationMax, times(isApplicable ? 1 : 0)).param("value", maxValue);
     }
 
@@ -168,7 +187,7 @@ public class MinimumMaximumRuleTest {
         JFieldVar result = rule.apply("node", node, null, fieldVar, null);
         assertSame(fieldVar, result);
 
-        verify(fieldVar, never()).annotate(Size.class);
+        verify(fieldVar, never()).annotate(sizeClass);
         verify(annotationMin, never()).param(anyString(), anyString());
         verify(annotationMax, never()).param(anyString(), anyString());
     }
@@ -179,9 +198,9 @@ public class MinimumMaximumRuleTest {
         JFieldVar result = rule.apply("node", node, null, fieldVar, null);
         assertSame(fieldVar, result);
 
-        verify(fieldVar, never()).annotate(DecimalMin.class);
+        verify(fieldVar, never()).annotate(decimalMinClass);
         verify(annotationMin, never()).param(anyString(), anyString());
-        verify(fieldVar, never()).annotate(DecimalMax.class);
+        verify(fieldVar, never()).annotate(decimalMaxClass);
         verify(annotationMax, never()).param(anyString(), anyString());
     }
 }
\ No newline at end of file
diff --git a/jsonschema2pojo-core/src/test/java/org/jsonschema2pojo/rules/PatternRuleTest.java b/jsonschema2pojo-core/src/test/java/org/jsonschema2pojo/rules/PatternRuleTest.java
index fe75dac1..5fc92217 100644
--- a/jsonschema2pojo-core/src/test/java/org/jsonschema2pojo/rules/PatternRuleTest.java
+++ b/jsonschema2pojo-core/src/test/java/org/jsonschema2pojo/rules/PatternRuleTest.java
@@ -21,12 +21,13 @@ import static org.junit.Assert.*;
 import static org.mockito.ArgumentMatchers.*;
 import static org.mockito.Mockito.*;
 
+import java.lang.annotation.Annotation;
 import java.lang.reflect.Array;
 import java.util.Collection;
 import java.util.Map;
 import java.util.UUID;
-
-import javax.validation.constraints.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import org.jsonschema2pojo.GenerationConfig;
 import org.jsonschema2pojo.NoopAnnotator;
@@ -43,6 +44,8 @@ import com.fasterxml.jackson.databind.JsonNode;
 import com.sun.codemodel.JAnnotationUse;
 import com.sun.codemodel.JFieldVar;
 
+import jakarta.validation.constraints.Pattern;
+
 /**
  * Tests {@link PatternRuleTest}
  */
@@ -52,6 +55,8 @@ public class PatternRuleTest {
     private final boolean isApplicable;
     private PatternRule rule;
     private Class<?> fieldClass;
+    private final boolean useJakartaValidation;
+    private final Class<? extends Annotation> patternClass;
     @Mock
     private GenerationConfig config;
     @Mock
@@ -75,19 +80,23 @@ public class PatternRuleTest {
                 { false, Long.class },
                 { false, Float.class },
                 { false, Double.class },
-        });
+        }).stream()
+                .flatMap(o -> Stream.of(true, false).map(b -> Stream.concat(stream(o), Stream.of(b)).toArray()))
+                .collect(Collectors.toList());
     }
 
-
-    public PatternRuleTest(boolean isApplicable, Class<?> fieldClass) {
+    public PatternRuleTest(boolean isApplicable, Class<?> fieldClass, boolean useJakartaValidation) {
         this.isApplicable = isApplicable;
         this.fieldClass = fieldClass;
+        this.useJakartaValidation = useJakartaValidation;
+        this.patternClass = useJakartaValidation ? Pattern.class : javax.validation.constraints.Pattern.class;
     }
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         rule = new PatternRule(new RuleFactory(config, new NoopAnnotator(), new SchemaStore()));
+        when(config.isUseJakartaValidation()).thenReturn(useJakartaValidation);
     }
 
     @Test
@@ -96,13 +105,13 @@ public class PatternRuleTest {
         final String patternValue = "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$";
 
         when(node.asText()).thenReturn(patternValue);
-        when(fieldVar.annotate(Pattern.class)).thenReturn(annotation);
+        when(fieldVar.annotate(patternClass)).thenReturn(annotation);
         when(fieldVar.type().boxify().fullName()).thenReturn(fieldClass.getTypeName());
 
         JFieldVar result = rule.apply("node", node, null, fieldVar, null);
         assertSame(fieldVar, result);
 
-        verify(fieldVar, times(isApplicable ? 1 : 0)).annotate(Pattern.class);
+        verify(fieldVar, times(isApplicable ? 1 : 0)).annotate(patternClass);
         verify(annotation, times(isApplicable ? 1 : 0)).param("regexp", patternValue);
     }
 
@@ -112,7 +121,7 @@ public class PatternRuleTest {
         JFieldVar result = rule.apply("node", node, null, fieldVar, null);
         assertSame(fieldVar, result);
 
-        verify(fieldVar, never()).annotate(Pattern.class);
+        verify(fieldVar, never()).annotate(patternClass);
         verify(annotation, never()).param(anyString(), anyString());
     }
 
diff --git a/jsonschema2pojo-core/src/test/java/org/jsonschema2pojo/rules/RequiredArrayRuleTest.java b/jsonschema2pojo-core/src/test/java/org/jsonschema2pojo/rules/RequiredArrayRuleTest.java
index 883cd4b4..80bf1d3e 100644
--- a/jsonschema2pojo-core/src/test/java/org/jsonschema2pojo/rules/RequiredArrayRuleTest.java
+++ b/jsonschema2pojo-core/src/test/java/org/jsonschema2pojo/rules/RequiredArrayRuleTest.java
@@ -16,17 +16,19 @@
 
 package org.jsonschema2pojo.rules;
 
+import static java.util.Arrays.asList;
 import static org.hamcrest.MatcherAssert.*;
 import static org.hamcrest.Matchers.*;
 import static org.mockito.Mockito.*;
 
+import java.lang.annotation.Annotation;
 import java.util.Collection;
 
-import javax.validation.constraints.NotNull;
-
 import org.jsonschema2pojo.GenerationConfig;
 import org.jsonschema2pojo.Schema;
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.node.ArrayNode;
@@ -37,12 +39,31 @@ import com.sun.codemodel.JDefinedClass;
 import com.sun.codemodel.JDocComment;
 import com.sun.codemodel.JMod;
 
+import jakarta.validation.constraints.NotNull;
+
+@RunWith(Parameterized.class)
 public class RequiredArrayRuleTest {
 
     private static final String TARGET_CLASS_NAME = RequiredArrayRuleTest.class.getName() + ".DummyClass";
 
     private RequiredArrayRule rule = new RequiredArrayRule(new RuleFactory());
 
+    private final boolean useJakartaValidation;
+    private final Class<? extends Annotation> notNullClass;
+
+    @Parameterized.Parameters
+    public static Collection<Object[]> data() {
+        return asList(new Object[][] {
+                { false, javax.validation.constraints.NotNull.class },
+                { true, NotNull.class }
+        });
+    }
+
+    public RequiredArrayRuleTest(boolean useJakartaValidation, Class<? extends Annotation> notNullClass) {
+        this.useJakartaValidation = useJakartaValidation;
+        this.notNullClass = notNullClass;
+    }
+
     @Test
     public void shouldUpdateJavaDoc() throws JClassAlreadyExistsException {
         JDefinedClass jclass = new JCodeModel()._class(TARGET_CLASS_NAME);
@@ -58,18 +79,16 @@ public class RequiredArrayRuleTest {
         JDocComment fooBarJavaDoc = jclass.fields().get("fooBar").javadoc();
         JDocComment fooJavaDoc = jclass.fields().get("foo").javadoc();
 
-
         assertThat(fooBarJavaDoc.size(), is(1));
         assertThat((String) fooBarJavaDoc.get(0), is("\n(Required)"));
 
         assertThat(fooJavaDoc.size(), is(0));
     }
 
-
     @Test
     public void shouldUpdateAnnotations() throws JClassAlreadyExistsException {
         setupRuleFactoryToIncludeJsr303();
-        
+
         JDefinedClass jclass = new JCodeModel()._class(TARGET_CLASS_NAME);
 
         jclass.field(JMod.PRIVATE, jclass.owner().ref(String.class), "fooBar");
@@ -84,11 +103,11 @@ public class RequiredArrayRuleTest {
         Collection<JAnnotationUse> fooAnnotations = jclass.fields().get("foo").annotations();
 
         assertThat(fooBarAnnotations.size(), is(1));
-        assertThat(fooBarAnnotations.iterator().next().getAnnotationClass().name(), is(NotNull.class.getSimpleName()));
+        assertThat(fooBarAnnotations.iterator().next().getAnnotationClass().name(), is(notNullClass.getSimpleName()));
 
         assertThat(fooAnnotations.size(), is(0));
     }
-    
+
     private void setupRuleFactoryToIncludeJsr303() {
         GenerationConfig config = mock(GenerationConfig.class);
         when(config.getPropertyWordDelimiters()).thenReturn(new char[] { '-', ' ', '_' });
@@ -96,5 +115,6 @@ public class RequiredArrayRuleTest {
         ruleFactory.setGenerationConfig(config);
         rule = new RequiredArrayRule(ruleFactory);
         when(config.isIncludeJsr303Annotations()).thenReturn(true);
+        when(config.isUseJakartaValidation()).thenReturn(useJakartaValidation);
     }
 }
diff --git a/jsonschema2pojo-integration-tests/pom.xml b/jsonschema2pojo-integration-tests/pom.xml
index 61238366..f802e2e2 100644
--- a/jsonschema2pojo-integration-tests/pom.xml
+++ b/jsonschema2pojo-integration-tests/pom.xml
@@ -144,17 +144,33 @@
             <artifactId>hamcrest-all</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.hibernate</groupId>
+            <groupId>org.hibernate.validator</groupId>
             <artifactId>hibernate-validator</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.glassfish</groupId>
+            <artifactId>jakarta.el</artifactId>
+        </dependency>
+        <!-- javax.validation implementation dependencies: start -->
+        <dependency>
+            <groupId>org.apache.bval</groupId>
+            <artifactId>bval-jsr303</artifactId>
+            <version>0.5</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>javax.validation</groupId>
+            <artifactId>validation-api</artifactId>
+        </dependency>
+        <!-- javax.validation implementation dependencies: end -->
         <dependency>
             <groupId>org.mockito</groupId>
             <artifactId>mockito-core</artifactId>
         </dependency>
         <dependency>
-           <groupId>org.robolectric</groupId>
-           <artifactId>robolectric</artifactId>
-       </dependency>
+            <groupId>org.robolectric</groupId>
+            <artifactId>robolectric</artifactId>
+        </dependency>
         <dependency>
             <groupId>qdox</groupId>
             <artifactId>qdox</artifactId>
diff --git a/jsonschema2pojo-integration-tests/src/test/java/org/jsonschema2pojo/integration/config/IncludeJsr303AnnotationsIT.java b/jsonschema2pojo-integration-tests/src/test/java/org/jsonschema2pojo/integration/config/IncludeJsr303AnnotationsIT.java
index 91c595f9..49fe40f1 100644
--- a/jsonschema2pojo-integration-tests/src/test/java/org/jsonschema2pojo/integration/config/IncludeJsr303AnnotationsIT.java
+++ b/jsonschema2pojo-integration-tests/src/test/java/org/jsonschema2pojo/integration/config/IncludeJsr303AnnotationsIT.java
@@ -27,48 +27,69 @@ import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.math.BigDecimal;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.Set;
 import java.util.UUID;
 
-import javax.validation.ConstraintViolation;
-import javax.validation.Validation;
-import javax.validation.Validator;
-
+import org.apache.bval.jsr303.ApacheValidationProvider;
 import org.hamcrest.Matcher;
 import org.jsonschema2pojo.integration.util.FileSearchMatcher;
 import org.jsonschema2pojo.integration.util.Jsonschema2PojoRule;
 import org.junit.Rule;
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import jakarta.validation.Validation;
+import jakarta.validation.Validator;
 
 @SuppressWarnings("rawtypes")
+@RunWith(Parameterized.class)
 public class IncludeJsr303AnnotationsIT {
 
+    private final boolean useJakartaValidation;
     @Rule public Jsonschema2PojoRule schemaRule = new Jsonschema2PojoRule();
 
-    private static Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
+    private static final javax.validation.Validator javaxValidator = javax.validation.Validation.byProvider(ApacheValidationProvider.class)
+            .configure()
+            .buildValidatorFactory()
+            .getValidator();
+    private static final Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
+
+    @Parameterized.Parameters
+    public static Collection<Object> data() {
+        return asList(true, false);
+    }
+
+    public IncludeJsr303AnnotationsIT(boolean useJakartaValidation) {
+        this.useJakartaValidation = useJakartaValidation;
+    }
 
     @Test
     public void jsrAnnotationsAreNotIncludedByDefault() {
-        File outputDirectory = schemaRule.generate("/schema/jsr303/all.json", "com.example");
+        File outputDirectory = schemaRule.generate("/schema/jsr303/all.json", "com.example",
+                config("useJakartaValidation", useJakartaValidation));
 
-        assertThat(outputDirectory, not(containsText("javax.validation")));
+        final String validationPackageName = useJakartaValidation ? "jakarta.validation" : "javax.validation";
+        assertThat(outputDirectory, not(containsText(validationPackageName)));
     }
 
     @Test
     public void jsrAnnotationsAreNotIncludedWhenSwitchedOff() {
         File outputDirectory = schemaRule.generate("/schema/jsr303/all.json", "com.example",
-                config("includeJsr303Annotations", false));
+                config("includeJsr303Annotations", false, "useJakartaValidation", useJakartaValidation));
 
-        assertThat(outputDirectory, not(containsText("javax.validation")));
+        final String validationPackageName = useJakartaValidation ? "jakarta.validation" : "javax.validation";
+        assertThat(outputDirectory, not(containsText(validationPackageName)));
     }
 
     @Test
     public void jsr303DecimalMinValidationIsAddedForSchemaRuleMinimum() throws ClassNotFoundException {
 
         ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/jsr303/minimum.json", "com.example",
-                config("includeJsr303Annotations", true));
+                config("includeJsr303Annotations", true, "useJakartaValidation", useJakartaValidation));
 
         Class generatedType = resultsClassLoader.loadClass("com.example.Minimum");
 
@@ -87,7 +108,7 @@ public class IncludeJsr303AnnotationsIT {
     public void jsr303DecimalMaxValidationIsAddedForSchemaRuleMaximum() throws ClassNotFoundException {
 
         ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/jsr303/maximum.json", "com.example",
-                config("includeJsr303Annotations", true));
+                config("includeJsr303Annotations", true, "useJakartaValidation", useJakartaValidation));
 
         Class generatedType = resultsClassLoader.loadClass("com.example.Maximum");
 
@@ -106,7 +127,7 @@ public class IncludeJsr303AnnotationsIT {
     public void jsr303SizeValidationIsAddedForSchemaRuleMinItems() throws ClassNotFoundException {
 
         ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/jsr303/minItems.json", "com.example",
-                config("includeJsr303Annotations", true));
+                config("includeJsr303Annotations", true, "useJakartaValidation", useJakartaValidation));
 
         Class generatedType = resultsClassLoader.loadClass("com.example.MinItems");
 
@@ -125,7 +146,7 @@ public class IncludeJsr303AnnotationsIT {
     public void jsr303SizeValidationIsAddedForSchemaRuleMaxItems() throws ClassNotFoundException {
 
         ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/jsr303/maxItems.json", "com.example",
-                config("includeJsr303Annotations", true));
+                config("includeJsr303Annotations", true, "useJakartaValidation", useJakartaValidation));
 
         Class generatedType = resultsClassLoader.loadClass("com.example.MaxItems");
 
@@ -143,7 +164,7 @@ public class IncludeJsr303AnnotationsIT {
     public void jsr303SizeValidationIsAddedForSchemaRuleMinItemsAndMaxItems() throws ClassNotFoundException {
 
         ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/jsr303/minAndMaxItems.json", "com.example",
-                config("includeJsr303Annotations", true));
+                config("includeJsr303Annotations", true, "useJakartaValidation", useJakartaValidation));
 
         Class generatedType = resultsClassLoader.loadClass("com.example.MinAndMaxItems");
 
@@ -165,7 +186,7 @@ public class IncludeJsr303AnnotationsIT {
     public void jsr303PatternValidationIsAddedForSchemaRulePattern() throws ClassNotFoundException {
 
         ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/jsr303/pattern.json", "com.example",
-                config("includeJsr303Annotations", true));
+                config("includeJsr303Annotations", true, "useJakartaValidation", useJakartaValidation));
 
         Class generatedType = resultsClassLoader.loadClass("com.example.Pattern");
 
@@ -183,7 +204,7 @@ public class IncludeJsr303AnnotationsIT {
     public void jsr303NotNullValidationIsAddedForSchemaRuleRequired() throws ClassNotFoundException {
 
         ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/jsr303/required.json", "com.example",
-                config("includeJsr303Annotations", true));
+                config("includeJsr303Annotations", true, "useJakartaValidation", useJakartaValidation));
 
         Class generatedType = resultsClassLoader.loadClass("com.example.Required");
 
@@ -200,7 +221,7 @@ public class IncludeJsr303AnnotationsIT {
     public void jsr303SizeValidationIsAddedForSchemaRuleMinLength() throws ClassNotFoundException {
 
         ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/jsr303/minLength.json", "com.example",
-                config("includeJsr303Annotations", true));
+                config("includeJsr303Annotations", true, "useJakartaValidation", useJakartaValidation));
 
         Class generatedType = resultsClassLoader.loadClass("com.example.MinLength");
 
@@ -218,7 +239,7 @@ public class IncludeJsr303AnnotationsIT {
     public void jsr303SizeValidationIsAddedForSchemaRuleMaxLength() throws ClassNotFoundException {
 
         ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/jsr303/maxLength.json", "com.example",
-                config("includeJsr303Annotations", true));
+                config("includeJsr303Annotations", true, "useJakartaValidation", useJakartaValidation));
 
         Class generatedType = resultsClassLoader.loadClass("com.example.MaxLength");
 
@@ -236,7 +257,7 @@ public class IncludeJsr303AnnotationsIT {
     public void jsr303DigitsValidationIsAddedForSchemaRuleDigits() throws ClassNotFoundException {
 
         ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/jsr303/digits.json", "com.example",
-            config("includeJsr303Annotations", true, "useBigDecimals", true));
+                config("includeJsr303Annotations", true, "useBigDecimals", true, "useJakartaValidation", useJakartaValidation));
 
         Class generatedType = resultsClassLoader.loadClass("com.example.Digits");
 
@@ -276,7 +297,7 @@ public class IncludeJsr303AnnotationsIT {
     @Test
     public void jsr303ValidAnnotationIsAddedForObject() throws ClassNotFoundException {
         ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/jsr303/validObject.json", "com.example",
-                config("includeJsr303Annotations", true));
+                config("includeJsr303Annotations", true, "useJakartaValidation", useJakartaValidation));
 
         Class validObjectType = resultsClassLoader.loadClass("com.example.ValidObject");
         Class objectFieldType = resultsClassLoader.loadClass("com.example.Objectfield");
@@ -295,7 +316,7 @@ public class IncludeJsr303AnnotationsIT {
     @Test
     public void jsr303ValidAnnotationIsAddedForArray() throws ClassNotFoundException {
         ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/jsr303/validArray.json", "com.example",
-                config("includeJsr303Annotations", true));
+                config("includeJsr303Annotations", true, "useJakartaValidation", useJakartaValidation));
 
         Class validArrayType = resultsClassLoader.loadClass("com.example.ValidArray");
         Class objectArrayType = resultsClassLoader.loadClass("com.example.Objectarray");
@@ -318,7 +339,7 @@ public class IncludeJsr303AnnotationsIT {
     @Test
     public void jsr303ValidAnnotationIsAddedForArrayWithRef() throws ClassNotFoundException {
         ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/jsr303/validArray.json", "com.example",
-                config("includeJsr303Annotations", true));
+                config("includeJsr303Annotations", true, "useJakartaValidation", useJakartaValidation));
 
         Class validArrayType = resultsClassLoader.loadClass("com.example.ValidArray");
         Class refarrayType = resultsClassLoader.loadClass("com.example.Product");
@@ -341,7 +362,8 @@ public class IncludeJsr303AnnotationsIT {
     @SuppressWarnings("unchecked")
     @Test
     public void jar303AnnotationsValidatedForAdditionalProperties() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
-        ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/jsr303/validAdditionalProperties.json", "com.example", config("includeJsr303Annotations", true));
+        ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/jsr303/validAdditionalProperties.json", "com.example",
+                config("includeJsr303Annotations", true, "useJakartaValidation", useJakartaValidation));
 
         Class parentType = resultsClassLoader.loadClass("com.example.ValidAdditionalProperties");
         Object parent = parentType.newInstance();
@@ -359,8 +381,8 @@ public class IncludeJsr303AnnotationsIT {
         assertNumberOfConstraintViolationsOn(parent, is(1));
     }
 
-    private static void assertNumberOfConstraintViolationsOn(Object instance, Matcher<Integer> matcher) {
-        Set<ConstraintViolation<Object>> violationsForValidInstance = validator.validate(instance);
+    private void assertNumberOfConstraintViolationsOn(Object instance, Matcher<Integer> matcher) {
+        final Set<?> violationsForValidInstance = useJakartaValidation ? validator.validate(instance) : javaxValidator.validate(instance);
         assertThat(violationsForValidInstance.size(), matcher);
     }
 
diff --git a/jsonschema2pojo-integration-tests/src/test/java/org/jsonschema2pojo/integration/config/IncludeJsr305AnnotationsIT.java b/jsonschema2pojo-integration-tests/src/test/java/org/jsonschema2pojo/integration/config/IncludeJsr305AnnotationsIT.java
index 06f6452d..ab0d5007 100644
--- a/jsonschema2pojo-integration-tests/src/test/java/org/jsonschema2pojo/integration/config/IncludeJsr305AnnotationsIT.java
+++ b/jsonschema2pojo-integration-tests/src/test/java/org/jsonschema2pojo/integration/config/IncludeJsr305AnnotationsIT.java
@@ -16,12 +16,14 @@
 
 package org.jsonschema2pojo.integration.config;
 
+import static java.util.Arrays.asList;
 import static org.hamcrest.Matchers.*;
 import static org.jsonschema2pojo.integration.util.CodeGenerationHelper.*;
 import static org.junit.Assert.*;
 
 import java.io.File;
 import java.lang.reflect.Field;
+import java.util.Collection;
 
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
@@ -31,25 +33,41 @@ import org.jsonschema2pojo.integration.util.FileSearchMatcher;
 import org.jsonschema2pojo.integration.util.Jsonschema2PojoRule;
 import org.junit.Rule;
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
 
+@RunWith(Parameterized.class)
 public class IncludeJsr305AnnotationsIT {
 
+    private final boolean useJakartaValidation;
     @Rule
     public Jsonschema2PojoRule schemaRule = new Jsonschema2PojoRule();
 
+    @Parameterized.Parameters
+    public static Collection<Object> data() {
+        return asList(true, false);
+    }
+
+    public IncludeJsr305AnnotationsIT(boolean useJakartaValidation) {
+        this.useJakartaValidation = useJakartaValidation;
+    }
+
     @Test
     public void jsrAnnotationsAreNotIncludedByDefault() {
-        File outputDirectory = schemaRule.generate("/schema/jsr303/all.json", "com.example");
+        File outputDirectory = schemaRule.generate("/schema/jsr303/all.json", "com.example",
+                config("useJakartaValidation", useJakartaValidation));
 
-        assertThat(outputDirectory, not(containsText("javax.validation")));
+        final String validationPackageName = useJakartaValidation ? "jakarta.validation" : "javax.validation";
+        assertThat(outputDirectory, not(containsText(validationPackageName)));
     }
 
     @Test
     public void jsrAnnotationsAreNotIncludedWhenSwitchedOff() {
         File outputDirectory = schemaRule.generate("/schema/jsr303/all.json", "com.example",
-                config("includeJsr305Annotations", false));
+                config("includeJsr305Annotations", false, "useJakartaValidation", useJakartaValidation));
 
-        assertThat(outputDirectory, not(containsText("javax.validation")));
+        final String validationPackageName = useJakartaValidation ? "jakarta.validation" : "javax.validation";
+        assertThat(outputDirectory, not(containsText(validationPackageName)));
     }
 
     @Test
@@ -57,7 +75,7 @@ public class IncludeJsr305AnnotationsIT {
     public void jsr305NonnullAnnotationIsAddedForSchemaRuleRequired() throws ClassNotFoundException {
 
         ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/jsr303/required.json", "com.example",
-                config("includeJsr305Annotations", true));
+                                                                       config("includeJsr305Annotations", true));
 
         Class generatedType = resultsClassLoader.loadClass("com.example.Required");
 
@@ -72,7 +90,7 @@ public class IncludeJsr305AnnotationsIT {
     @SuppressWarnings("rawtypes")
     public void jsr305NullableAnnotationIsAddedByDefault() throws ClassNotFoundException {
         ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/required/required.json", "com.example",
-                config("includeJsr305Annotations", true));
+                                                                       config("includeJsr305Annotations", true));
 
         Class generatedType = resultsClassLoader.loadClass("com.example.Required");
 
@@ -89,7 +107,7 @@ public class IncludeJsr305AnnotationsIT {
     @SuppressWarnings("rawtypes")
     public void jsr305RequiredArrayIsTakenIntoConsideration() throws ClassNotFoundException {
         ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/required/requiredArray.json", "com.example",
-                config("includeJsr305Annotations", true));
+                                                                       config("includeJsr305Annotations", true));
 
         Class generatedType = resultsClassLoader.loadClass("com.example.RequiredArray");
 
@@ -106,7 +124,7 @@ public class IncludeJsr305AnnotationsIT {
     @SuppressWarnings("rawtypes")
     public void jsr305AnnotationsGeneratedProperlyInNestedArray() throws ClassNotFoundException, NoSuchFieldException {
         ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/required/requiredNestedInArray.json", "com.example",
-                config("includeJsr305Annotations", true));
+                                                                       config("includeJsr305Annotations", true));
 
         Class generatedType = resultsClassLoader.loadClass("com.example.Nested");
 
@@ -118,7 +136,7 @@ public class IncludeJsr305AnnotationsIT {
     @SuppressWarnings("rawtypes")
     public void jsr305AnnotationsGeneratedProperlyInNestedObject() throws ClassNotFoundException, NoSuchFieldException {
         ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/required/requiredNestedInObject.json", "com.example",
-                config("includeJsr305Annotations", true));
+                                                                       config("includeJsr305Annotations", true));
 
         Class generatedType = resultsClassLoader.loadClass("com.example.Nested");