feat: allow json-jackson to auto-discover modules

Signed-off-by: Théo Gaillard <theo.gaillard@protonmail.com>
diff --git a/media/json-jackson/pom.xml b/media/json-jackson/pom.xml
index 4e2c900..c7d66b5 100644
--- a/media/json-jackson/pom.xml
+++ b/media/json-jackson/pom.xml
@@ -123,5 +123,18 @@
             <artifactId>junit</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.test-framework.providers</groupId>
+            <artifactId>jersey-test-framework-provider-bundle</artifactId>
+            <version>${project.version}</version>
+            <type>pom</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.datatype</groupId>
+            <artifactId>jackson-datatype-jdk8</artifactId>
+            <version>2.11.0</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 </project>
diff --git a/media/json-jackson/src/main/java/org/glassfish/jersey/jackson/JacksonFeature.java b/media/json-jackson/src/main/java/org/glassfish/jersey/jackson/JacksonFeature.java
index 2ab2501..95af305 100644
--- a/media/json-jackson/src/main/java/org/glassfish/jersey/jackson/JacksonFeature.java
+++ b/media/json-jackson/src/main/java/org/glassfish/jersey/jackson/JacksonFeature.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
@@ -25,6 +25,7 @@
 import org.glassfish.jersey.CommonProperties;
 import org.glassfish.jersey.internal.InternalProperties;
 import org.glassfish.jersey.internal.util.PropertiesHelper;
+import org.glassfish.jersey.jackson.internal.DefaultJacksonJaxbJsonProvider;
 import org.glassfish.jersey.jackson.internal.FilteringJacksonJaxbJsonProvider;
 import org.glassfish.jersey.jackson.internal.JacksonFilteringFeature;
 import org.glassfish.jersey.jackson.internal.jackson.jaxrs.base.JsonMappingExceptionMapper;
@@ -103,7 +104,7 @@
                 context.register(JacksonFilteringFeature.class);
                 context.register(FilteringJacksonJaxbJsonProvider.class, MessageBodyReader.class, MessageBodyWriter.class);
             } else {
-                context.register(JacksonJaxbJsonProvider.class, MessageBodyReader.class, MessageBodyWriter.class);
+                context.register(DefaultJacksonJaxbJsonProvider.class, MessageBodyReader.class, MessageBodyWriter.class);
             }
         }
 
diff --git a/media/json-jackson/src/main/java/org/glassfish/jersey/jackson/internal/DefaultJacksonJaxbJsonProvider.java b/media/json-jackson/src/main/java/org/glassfish/jersey/jackson/internal/DefaultJacksonJaxbJsonProvider.java
new file mode 100644
index 0000000..8b4ce1c
--- /dev/null
+++ b/media/json-jackson/src/main/java/org/glassfish/jersey/jackson/internal/DefaultJacksonJaxbJsonProvider.java
@@ -0,0 +1,52 @@
+/*
+ * 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.jackson.internal;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.glassfish.jersey.jackson.internal.jackson.jaxrs.cfg.Annotations;
+import org.glassfish.jersey.jackson.internal.jackson.jaxrs.json.JacksonJaxbJsonProvider;
+
+import java.util.Objects;
+import javax.inject.Singleton;
+
+/**
+ * Entity Data provider based on Jackson JSON provider.
+ */
+@Singleton
+public class DefaultJacksonJaxbJsonProvider extends JacksonJaxbJsonProvider {
+
+    public DefaultJacksonJaxbJsonProvider() {
+        findAndRegisterModules();
+    }
+
+    public DefaultJacksonJaxbJsonProvider(final Annotations... annotationsToUse) {
+        super(annotationsToUse);
+        findAndRegisterModules();
+    }
+
+    private void findAndRegisterModules() {
+        final ObjectMapper defaultMapper = _mapperConfig.getDefaultMapper();
+        if (Objects.nonNull(defaultMapper)) {
+            defaultMapper.findAndRegisterModules();
+        }
+
+        final ObjectMapper mapper = _mapperConfig.getConfiguredMapper();
+        if (Objects.nonNull(mapper)) {
+            mapper.findAndRegisterModules();
+        }
+    }
+}
diff --git a/media/json-jackson/src/main/java/org/glassfish/jersey/jackson/internal/FilteringJacksonJaxbJsonProvider.java b/media/json-jackson/src/main/java/org/glassfish/jersey/jackson/internal/FilteringJacksonJaxbJsonProvider.java
index edf25f8..328697c 100644
--- a/media/json-jackson/src/main/java/org/glassfish/jersey/jackson/internal/FilteringJacksonJaxbJsonProvider.java
+++ b/media/json-jackson/src/main/java/org/glassfish/jersey/jackson/internal/FilteringJacksonJaxbJsonProvider.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -33,7 +33,6 @@
 import org.glassfish.jersey.jackson.internal.jackson.jaxrs.cfg.EndpointConfigBase;
 import org.glassfish.jersey.jackson.internal.jackson.jaxrs.cfg.ObjectWriterInjector;
 import org.glassfish.jersey.jackson.internal.jackson.jaxrs.cfg.ObjectWriterModifier;
-import org.glassfish.jersey.jackson.internal.jackson.jaxrs.json.JacksonJaxbJsonProvider;
 import org.glassfish.jersey.jackson.internal.jackson.jaxrs.json.JsonEndpointConfig;
 import org.glassfish.jersey.message.filtering.spi.ObjectProvider;
 
@@ -56,7 +55,7 @@
  * @author Michal Gajdos
  */
 @Singleton
-public final class FilteringJacksonJaxbJsonProvider extends JacksonJaxbJsonProvider {
+public final class FilteringJacksonJaxbJsonProvider extends DefaultJacksonJaxbJsonProvider {
 
     @Inject
     private Provider<ObjectProvider<FilterProvider>> provider;
diff --git a/media/json-jackson/src/test/java/org/glassfish/jersey/jackson/internal/DefaultJacksonJaxbJsonProviderTest.java b/media/json-jackson/src/test/java/org/glassfish/jersey/jackson/internal/DefaultJacksonJaxbJsonProviderTest.java
new file mode 100644
index 0000000..281d4c4
--- /dev/null
+++ b/media/json-jackson/src/test/java/org/glassfish/jersey/jackson/internal/DefaultJacksonJaxbJsonProviderTest.java
@@ -0,0 +1,40 @@
+/*
+ * 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.jackson.internal;
+
+import org.glassfish.jersey.jackson.internal.model.ServiceTest;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.Test;
+
+import javax.ws.rs.core.Application;
+
+import static junit.framework.TestCase.assertEquals;
+
+public final class DefaultJacksonJaxbJsonProviderTest extends JerseyTest {
+
+    @Override
+    protected final Application configure() {
+        return new ResourceConfig(ServiceTest.class);
+    }
+
+    @Test
+    public final void testJavaOptional() {
+        final String response = target("entity/simple").request().get(String.class);
+        assertEquals("{\"name\":\"Hello\",\"value\":\"World\"}", response);
+    }
+}
diff --git a/media/json-jackson/src/test/java/org/glassfish/jersey/jackson/internal/model/ServiceTest.java b/media/json-jackson/src/test/java/org/glassfish/jersey/jackson/internal/model/ServiceTest.java
new file mode 100644
index 0000000..027064b
--- /dev/null
+++ b/media/json-jackson/src/test/java/org/glassfish/jersey/jackson/internal/model/ServiceTest.java
@@ -0,0 +1,58 @@
+/*
+ * 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.jackson.internal.model;
+
+import com.fasterxml.jackson.annotation.JsonGetter;
+
+import java.util.Optional;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+@Path("/entity/")
+public final class ServiceTest {
+
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    @Path("/simple")
+    public final EntityTest simple() {
+        return new EntityTest("Hello", "World");
+    }
+
+    private static final class EntityTest {
+
+        private final String name;
+
+        private final String value;
+
+        EntityTest(final String name, final String value) {
+            this.name = name;
+            this.value = value;
+        }
+
+        @JsonGetter("name")
+        public final String getName() {
+            return name;
+        }
+
+        @JsonGetter("value")
+        public final Optional<String> getValue() {
+            return Optional.ofNullable(value);
+        }
+    }
+}