Make JAX-B API optional (#4634)

* Make JAX-B API optional

Signed-off-by: Jan Supol <jan.supol@oracle.com>
diff --git a/ext/bean-validation/pom.xml b/ext/bean-validation/pom.xml
index b33e994..30da28d 100644
--- a/ext/bean-validation/pom.xml
+++ b/ext/bean-validation/pom.xml
@@ -98,6 +98,11 @@
             </exclusions>
         </dependency>
         <dependency>
+            <groupId>jakarta.xml.bind</groupId>
+            <artifactId>jakarta.xml.bind-api</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
             <groupId>javax.enterprise</groupId>
             <artifactId>cdi-api</artifactId>
             <optional>true</optional>
diff --git a/ext/bean-validation/src/main/java/org/glassfish/jersey/server/validation/ValidationError.java b/ext/bean-validation/src/main/java/org/glassfish/jersey/server/validation/ValidationError.java
index cf2f1c4..a737399 100644
--- a/ext/bean-validation/src/main/java/org/glassfish/jersey/server/validation/ValidationError.java
+++ b/ext/bean-validation/src/main/java/org/glassfish/jersey/server/validation/ValidationError.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -25,15 +25,7 @@
  */
 @XmlRootElement
 @SuppressWarnings("UnusedDeclaration")
-public final class ValidationError {
-
-    private String message;
-
-    private String messageTemplate;
-
-    private String path;
-
-    private String invalidValue;
+public final class ValidationError extends ValidationErrorData {
 
     /**
      * Create a {@code ValidationError} instance. Constructor for JAXB providers.
@@ -50,81 +42,6 @@
      * @param invalidValue value that failed to pass constraints.
      */
     public ValidationError(final String message, final String messageTemplate, final String path, final String invalidValue) {
-        this.message = message;
-        this.messageTemplate = messageTemplate;
-        this.path = path;
-        this.invalidValue = invalidValue;
-    }
-
-    /**
-     * Return the interpolated error message for this validation error.
-     *
-     * @return the interpolated error message for this validation error.
-     */
-    public String getMessage() {
-        return message;
-    }
-
-    /**
-     * Return the interpolated error message for this validation error.
-     *
-     * @param message the interpolated error message for this validation error.
-     */
-    public void setMessage(final String message) {
-        this.message = message;
-    }
-
-    /**
-     * Return the string representation of the property path to the value.
-     *
-     * @return the string representation of the property path to the value.
-     */
-    public String getPath() {
-        return path;
-    }
-
-    /**
-     * Set the string representation of the property path to the value.
-     *
-     * @param path the string representation of the property path to the value.
-     */
-    public void setPath(final String path) {
-        this.path = path;
-    }
-
-    /**
-     * Returns the string representation of the value failing to pass the constraint.
-     *
-     * @return the value failing to pass the constraint.
-     */
-    public String getInvalidValue() {
-        return invalidValue;
-    }
-
-    /**
-     * Set the value failing to pass the constraint.
-     *
-     * @param invalidValue the value failing to pass the constraint.
-     */
-    public void setInvalidValue(final String invalidValue) {
-        this.invalidValue = invalidValue;
-    }
-
-    /**
-     * Return the non-interpolated error message for this validation error.
-     *
-     * @return the non-interpolated error message for this validation error.
-     */
-    public String getMessageTemplate() {
-        return messageTemplate;
-    }
-
-    /**
-     * Set the non-interpolated error message for this validation error.
-     *
-     * @param messageTemplate the non-interpolated error message for this validation error.
-     */
-    public void setMessageTemplate(final String messageTemplate) {
-        this.messageTemplate = messageTemplate;
+        super(message, messageTemplate, path, invalidValue);
     }
 }
diff --git a/ext/bean-validation/src/main/java/org/glassfish/jersey/server/validation/ValidationErrorData.java b/ext/bean-validation/src/main/java/org/glassfish/jersey/server/validation/ValidationErrorData.java
new file mode 100644
index 0000000..5c2abe6
--- /dev/null
+++ b/ext/bean-validation/src/main/java/org/glassfish/jersey/server/validation/ValidationErrorData.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.server.validation;
+
+
+import org.glassfish.jersey.internal.util.ReflectionHelper;
+
+/**
+ * Validation error entity to be included in {@code Response} if JAX-B API is not available
+ */
+@SuppressWarnings("UnusedDeclaration")
+public class ValidationErrorData {
+
+    protected String message;
+
+    protected String messageTemplate;
+
+    protected String path;
+
+    protected String invalidValue;
+
+    /* package */ ValidationErrorData() {
+    }
+
+    /**
+     * Create a {@code ValidationError} instance.
+     *
+     * @param message interpolated error message.
+     * @param messageTemplate non-interpolated error message.
+     * @param path property path.
+     * @param invalidValue value that failed to pass constraints.
+     */
+    /* package */
+    ValidationErrorData(final String message, final String messageTemplate, final String path, final String invalidValue) {
+        this.message = message;
+        this.messageTemplate = messageTemplate;
+        this.path = path;
+        this.invalidValue = invalidValue;
+    }
+
+    /**
+     * Return the interpolated error message for this validation error.
+     *
+     * @return the interpolated error message for this validation error.
+     */
+    public String getMessage() {
+        return message;
+    }
+
+    /**
+     * Return the interpolated error message for this validation error.
+     *
+     * @param message the interpolated error message for this validation error.
+     */
+    public void setMessage(final String message) {
+        this.message = message;
+    }
+
+    /**
+     * Return the string representation of the property path to the value.
+     *
+     * @return the string representation of the property path to the value.
+     */
+    public String getPath() {
+        return path;
+    }
+
+    /**
+     * Set the string representation of the property path to the value.
+     *
+     * @param path the string representation of the property path to the value.
+     */
+    public void setPath(final String path) {
+        this.path = path;
+    }
+
+    /**
+     * Returns the string representation of the value failing to pass the constraint.
+     *
+     * @return the value failing to pass the constraint.
+     */
+    public String getInvalidValue() {
+        return invalidValue;
+    }
+
+    /**
+     * Set the value failing to pass the constraint.
+     *
+     * @param invalidValue the value failing to pass the constraint.
+     */
+    public void setInvalidValue(final String invalidValue) {
+        this.invalidValue = invalidValue;
+    }
+
+    /**
+     * Return the non-interpolated error message for this validation error.
+     *
+     * @return the non-interpolated error message for this validation error.
+     */
+    public String getMessageTemplate() {
+        return messageTemplate;
+    }
+
+    /**
+     * Set the non-interpolated error message for this validation error.
+     *
+     * @param messageTemplate the non-interpolated error message for this validation error.
+     */
+    public void setMessageTemplate(final String messageTemplate) {
+        this.messageTemplate = messageTemplate;
+    }
+
+    /*
+     * Cache the information
+     */
+    private static Boolean isJaxbAvailable = null;
+
+    private static boolean isJaxbAvailable() {
+        if (isJaxbAvailable == null) {
+            isJaxbAvailable = ReflectionHelper.isJaxbAvailable();
+        }
+        return isJaxbAvailable;
+    }
+
+    /**
+     * A factory method that creates either JAX-B annotated data if JAX-B is available or POJO data otherwise.
+     * @param message interpolated error message.
+     * @param messageTemplate non-interpolated error message.
+     * @param path property path.
+     * @param invalidValue value that failed to pass constraints.
+     * @return ValidationErrorData subclass or itself
+     */
+    public static ValidationErrorData createValidationError(
+            final String message, final String messageTemplate, final String path, final String invalidValue) {
+        if (isJaxbAvailable()) {
+            return new ValidationError(message, messageTemplate, path, invalidValue);
+        } else {
+            return new ValidationErrorData(message, messageTemplate, path, invalidValue);
+        }
+    }
+}
diff --git a/ext/bean-validation/src/main/java/org/glassfish/jersey/server/validation/internal/ValidationErrorMessageBodyWriter.java b/ext/bean-validation/src/main/java/org/glassfish/jersey/server/validation/internal/ValidationErrorMessageBodyWriter.java
index 84e2a00..4c91fc5 100644
--- a/ext/bean-validation/src/main/java/org/glassfish/jersey/server/validation/internal/ValidationErrorMessageBodyWriter.java
+++ b/ext/bean-validation/src/main/java/org/glassfish/jersey/server/validation/internal/ValidationErrorMessageBodyWriter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -30,10 +30,10 @@
 import javax.ws.rs.ext.MessageBodyWriter;
 
 import org.glassfish.jersey.message.MessageUtils;
-import org.glassfish.jersey.server.validation.ValidationError;
+import org.glassfish.jersey.server.validation.ValidationErrorData;
 
 /**
- * {@link MessageBodyWriter} providing support for (collections of) {@link ValidationError}
+ * {@link MessageBodyWriter} providing support for (collections of) {@link ValidationErrorData}
  * that is able to output instances to {@code text/plain}/{@code text/html}.
  *
  * @author Michal Gajdos
@@ -49,10 +49,10 @@
     }
 
     private static boolean isSupportedType(final Class<?> type, final Type genericType) {
-        if (ValidationError.class.isAssignableFrom(type)) {
+        if (ValidationErrorData.class.isAssignableFrom(type)) {
             return true;
         } else if (Collection.class.isAssignableFrom(type) && (genericType instanceof ParameterizedType)) {
-            return ValidationError.class
+            return ValidationErrorData.class
                     .isAssignableFrom((Class) ((ParameterizedType) genericType).getActualTypeArguments()[0]);
         }
         return false;
@@ -79,13 +79,13 @@
                         final MediaType mediaType,
                         final MultivaluedMap<String, Object> httpHeaders,
                         final OutputStream entityStream) throws IOException, WebApplicationException {
-        final Collection<ValidationError> errors;
+        final Collection<ValidationErrorData> errors;
 
-        if (entity instanceof ValidationError) {
-            errors = Collections.singleton((ValidationError) entity);
+        if (entity instanceof ValidationErrorData) {
+            errors = Collections.singleton((ValidationErrorData) entity);
         } else {
             //noinspection unchecked
-            errors = (Collection<ValidationError>) entity;
+            errors = (Collection<ValidationErrorData>) entity;
         }
 
         final boolean isPlain = MediaType.TEXT_PLAIN_TYPE.getSubtype().equals(mediaType.getSubtype());
@@ -97,7 +97,7 @@
             builder.append("<div class=\"validation-errors\">");
         }
 
-        for (final ValidationError error : errors) {
+        for (final ValidationErrorData error : errors) {
             if (!isPlain) {
                 builder.append("<div class=\"validation-error\">");
             }
diff --git a/ext/bean-validation/src/main/java/org/glassfish/jersey/server/validation/internal/ValidationExceptionMapper.java b/ext/bean-validation/src/main/java/org/glassfish/jersey/server/validation/internal/ValidationExceptionMapper.java
index b569607..5e44507 100644
--- a/ext/bean-validation/src/main/java/org/glassfish/jersey/server/validation/internal/ValidationExceptionMapper.java
+++ b/ext/bean-validation/src/main/java/org/glassfish/jersey/server/validation/internal/ValidationExceptionMapper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -35,12 +35,12 @@
 import javax.validation.ValidationException;
 
 import org.glassfish.jersey.server.ServerProperties;
-import org.glassfish.jersey.server.validation.ValidationError;
+import org.glassfish.jersey.server.validation.ValidationErrorData;
 
 /**
  * {@link ExceptionMapper} for {@link ValidationException}.
  * <p/>
- * If {@value ServerProperties#BV_SEND_ERROR_IN_RESPONSE} property is enabled then a list of {@link ValidationError}
+ * If {@value ServerProperties#BV_SEND_ERROR_IN_RESPONSE} property is enabled then a list of {@link ValidationErrorData}
  * instances is sent in {@link Response} as well (in addition to HTTP 400/500 status code). Supported media types are:
  * {@code application/json}/{@code application/xml} (in appropriate provider is registered on server) or
  * {@code text/html}/{@code text/plain} (via custom {@link ValidationErrorMessageBodyWriter}).
@@ -85,7 +85,7 @@
                 response.entity(
                         new GenericEntity<>(
                                 ValidationHelper.constraintViolationToValidationErrors(cve),
-                                new GenericType<List<ValidationError>>() {}.getType()
+                                new GenericType<List<ValidationErrorData>>() {}.getType()
                         )
                 );
             }
diff --git a/ext/bean-validation/src/main/java/org/glassfish/jersey/server/validation/internal/ValidationHelper.java b/ext/bean-validation/src/main/java/org/glassfish/jersey/server/validation/internal/ValidationHelper.java
index 5e92de9..0722dd4 100644
--- a/ext/bean-validation/src/main/java/org/glassfish/jersey/server/validation/internal/ValidationHelper.java
+++ b/ext/bean-validation/src/main/java/org/glassfish/jersey/server/validation/internal/ValidationHelper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -27,7 +27,7 @@
 import javax.validation.Path;
 import javax.ws.rs.core.Response;
 
-import org.glassfish.jersey.server.validation.ValidationError;
+import org.glassfish.jersey.server.validation.ValidationErrorData;
 
 /**
  * Utility methods for Bean Validation processing.
@@ -39,13 +39,13 @@
 
     /**
      * Extract {@link ConstraintViolation constraint violations} from given exception and transform them into a list of
-     * {@link ValidationError validation errors}.
+     * {@link ValidationErrorData validation errors}.
      *
      * @param violation exception containing constraint violations.
      * @return list of validation errors (not {@code null}).
      */
-    public static List<ValidationError> constraintViolationToValidationErrors(final ConstraintViolationException violation) {
-        return violation.getConstraintViolations().stream().map(violation1 -> new ValidationError(
+    public static List<ValidationErrorData> constraintViolationToValidationErrors(final ConstraintViolationException violation) {
+        return violation.getConstraintViolations().stream().map(violation1 -> ValidationErrorData.createValidationError(
                 violation1.getMessage(),
                 violation1.getMessageTemplate(),
                 getViolationPath(violation1),
diff --git a/ext/entity-filtering/pom.xml b/ext/entity-filtering/pom.xml
index 60b5b98..9e90d30 100644
--- a/ext/entity-filtering/pom.xml
+++ b/ext/entity-filtering/pom.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0"?>
 <!--
 
-    Copyright (c) 2013, 2019 Oracle and/or its affiliates. All rights reserved.
+    Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
 
     This program and the accompanying materials are made available under the
     terms of the Eclipse Public License v. 2.0, which is available at
@@ -35,6 +35,11 @@
 
     <dependencies>
         <dependency>
+            <groupId>jakarta.xml.bind</groupId>
+            <artifactId>jakarta.xml.bind-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
             <groupId>org.glassfish.jersey.core</groupId>
             <artifactId>jersey-client</artifactId>
             <version>${project.version}</version>
diff --git a/ext/wadl-doclet/pom.xml b/ext/wadl-doclet/pom.xml
index dab9887..2282eef 100644
--- a/ext/wadl-doclet/pom.xml
+++ b/ext/wadl-doclet/pom.xml
@@ -44,21 +44,6 @@
 
     <profiles>
         <profile>
-            <id>jdk1.7</id>
-            <activation>
-                <jdk>1.7</jdk>
-            </activation>
-            <dependencies>
-                <dependency>
-                    <groupId>com.sun</groupId>
-                    <artifactId>tools</artifactId>
-                    <version>1.7.0</version>
-                    <scope>system</scope>
-                    <systemPath>${java.home}/../lib/tools.jar</systemPath>
-                </dependency>
-            </dependencies>
-        </profile>
-        <profile>
             <id>jdk1.8</id>
             <activation>
                 <jdk>1.8</jdk>
@@ -201,29 +186,19 @@
                 </plugins>
             </build>
         </profile>
-        <profile>
-            <id>tools.jar</id>
-            <activation>
-                <!-- Activation should be done with <file>${java.home}/../lib/tools.jar</file But this is not working with maven as the property is not expansed. -->
-                <property>
-                    <name>java.vendor</name>
-                    <value>Sun Microsystems Inc.</value>
-                </property>
-            </activation>
-            <dependencies>
-                <dependency>
-                    <groupId>com.sun</groupId>
-                    <artifactId>tools</artifactId>
-                    <version>1.6</version>
-                    <scope>system</scope>
-                    <systemPath>${java.home}/../lib/tools.jar</systemPath>
-                </dependency>
-            </dependencies>
-        </profile>
     </profiles>
 
     <dependencies>
         <dependency>
+            <groupId>jakarta.xml.bind</groupId>
+            <artifactId>jakarta.xml.bind-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.media</groupId>
+            <artifactId>jersey-media-jaxb</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
             <groupId>xerces</groupId>
             <artifactId>xercesImpl</artifactId>
         </dependency>