This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch spring6
in repository https://gitbox.apache.org/repos/asf/isis.git


The following commit(s) were added to refs/heads/spring6 by this push:
     new 9f79b8d520 ISIS-3275: properly handle JsonProviderForJaxb registration
9f79b8d520 is described below

commit 9f79b8d52064c11b3e5969573895268ef241a6e3
Author: Andi Huber <[email protected]>
AuthorDate: Fri Dec 16 17:30:07 2022 +0100

    ISIS-3275: properly handle JsonProviderForJaxb registration
    
    - fixes RestServiceTest
---
 commons/pom.xml                                    | 19 +++++++++++++++++
 commons/src/main/java/module-info.java             |  1 +
 .../org/apache/causeway/commons/io/JsonUtils.java  |  9 ++++++++
 persistence/jpa/applib/pom.xml                     | 21 -------------------
 .../causeway/testdomain/rest/RestServiceTest.java  |  9 +-------
 .../restfulobjects/client/ResponseDigester.java    | 22 +++++++++++++-------
 .../restfulobjects/client/RestfulClient.java       | 24 ++++++++++++----------
 .../restfulobjects/client/RestfulClientConfig.java |  6 ++++++
 8 files changed, 64 insertions(+), 47 deletions(-)

diff --git a/commons/pom.xml b/commons/pom.xml
index c173cb2a2e..d2e6c1dbd1 100644
--- a/commons/pom.xml
+++ b/commons/pom.xml
@@ -54,6 +54,25 @@
        </build>
 
        <dependencies>
+               
+               <dependency>
+                       <groupId>org.eclipse.persistence</groupId>
+                       <artifactId>org.eclipse.persistence.moxy</artifactId>
+                       <exclusions>
+                               <exclusion>
+                                       <groupId>org.ow2.asm</groupId>
+                                       <artifactId>asm</artifactId>
+                               </exclusion>
+                               <exclusion>
+                                       <groupId>org.ow2.asm</groupId>
+                                       <artifactId>asm-tree</artifactId>
+                               </exclusion>
+                               <exclusion>
+                                       <groupId>org.ow2.asm</groupId>
+                                       <artifactId>asm-analysis</artifactId>
+                               </exclusion>
+                       </exclusions>
+               </dependency>
 
                <dependency>
                        <groupId>com.fasterxml.woodstox</groupId>
diff --git a/commons/src/main/java/module-info.java 
b/commons/src/main/java/module-info.java
index 05bc7cabaa..117828d4aa 100644
--- a/commons/src/main/java/module-info.java
+++ b/commons/src/main/java/module-info.java
@@ -76,6 +76,7 @@ module org.apache.causeway.commons {
     requires transitive jakarta.xml.bind;
     requires transitive jakarta.inject;
     requires jakarta.annotation;
+    requires org.eclipse.persistence.moxy;
 
     // JAXB JUnit test
     opens org.apache.causeway.commons.internal.resources to jakarta.xml.bind;
diff --git 
a/commons/src/main/java/org/apache/causeway/commons/io/JsonUtils.java 
b/commons/src/main/java/org/apache/causeway/commons/io/JsonUtils.java
index 04efc8c307..00c9cb46eb 100644
--- a/commons/src/main/java/org/apache/causeway/commons/io/JsonUtils.java
+++ b/commons/src/main/java/org/apache/causeway/commons/io/JsonUtils.java
@@ -45,6 +45,13 @@ import lombok.experimental.UtilityClass;
 @UtilityClass
 public class JsonUtils {
 
+    /**
+     * Consumers of the framework may choose to use a different provider.
+     */
+    public Class<?> getPlatformDefaultJsonProviderForJaxb() {
+        return org.eclipse.persistence.jaxb.rs.MOXyJsonProvider.class;
+    }
+
     @FunctionalInterface
     public interface JsonCustomizer extends UnaryOperator<ObjectMapper> {}
 
@@ -148,4 +155,6 @@ public class JsonUtils {
         return mapper;
     }
 
+
+
 }
diff --git a/persistence/jpa/applib/pom.xml b/persistence/jpa/applib/pom.xml
index 594eada19e..8b01f61a0c 100644
--- a/persistence/jpa/applib/pom.xml
+++ b/persistence/jpa/applib/pom.xml
@@ -88,27 +88,6 @@
                        <scope>provided</scope>
         </dependency>
 
-        <!-- TODO JPA API (providing compile dependency) -->
-               <dependency>
-                       <groupId>org.eclipse.persistence</groupId>
-                       <artifactId>org.eclipse.persistence.moxy</artifactId>
-                       <version>4.0.0</version>
-                       <exclusions>
-                               <exclusion>
-                                       <groupId>org.ow2.asm</groupId>
-                                       <artifactId>asm</artifactId>
-                               </exclusion>
-                               <exclusion>
-                                       <groupId>org.ow2.asm</groupId>
-                                       <artifactId>asm-tree</artifactId>
-                               </exclusion>
-                               <exclusion>
-                                       <groupId>org.ow2.asm</groupId>
-                                       <artifactId>asm-analysis</artifactId>
-                               </exclusion>
-                       </exclusions>
-               </dependency>
-
        </dependencies>
 
 
diff --git 
a/regressiontests/stable-rest/src/test/java/org/apache/causeway/testdomain/rest/RestServiceTest.java
 
b/regressiontests/stable-rest/src/test/java/org/apache/causeway/testdomain/rest/RestServiceTest.java
index c74cbf1687..37175d973b 100644
--- 
a/regressiontests/stable-rest/src/test/java/org/apache/causeway/testdomain/rest/RestServiceTest.java
+++ 
b/regressiontests/stable-rest/src/test/java/org/apache/causeway/testdomain/rest/RestServiceTest.java
@@ -23,7 +23,6 @@ import jakarta.xml.bind.JAXBException;
 
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.condition.DisabledIfSystemProperty;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.web.server.LocalServerPort;
 import org.springframework.context.annotation.Import;
@@ -175,13 +174,7 @@ class RestServiceTest {
 
     }
 
-    //TODO[ISIS-3275] throws (seems jakarta annotations are not properly 
recognized)
-    /*
-     * Caused by: 
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized 
field "bookNameForTab1" (class 
org.apache.causeway.testdomain.jdo.JdoInventoryJaxbVm), not marked as ignorable 
(10 known properties: "productsForTab1", "productsForTab2", "favoriteBook", 
"books", "name", "inventory", "bookForTab2", "booksForTab1", "bookForTab1", 
"booksForTab2"])
- at [Source: 
(org.jboss.resteasy.specimpl.AbstractBuiltResponse$InputStreamWrapper); line: 
1, column: 21] (through reference chain: 
org.apache.causeway.testdomain.jdo.JdoInventoryJaxbVm["bookNameForTab1"])
-    at 
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:61)
-     */
-    @Test @DisabledIfSystemProperty(named = "isRunningWithSurefire", matches = 
"true")
+    @Test
     void inventoryAsJaxbVm_viaRestEndpoint() {
 
         assertTrue(restService.getPort()>0);
diff --git 
a/viewers/restfulobjects/client/src/main/java/org/apache/causeway/viewer/restfulobjects/client/ResponseDigester.java
 
b/viewers/restfulobjects/client/src/main/java/org/apache/causeway/viewer/restfulobjects/client/ResponseDigester.java
index ea280366f6..0482c7c54d 100644
--- 
a/viewers/restfulobjects/client/src/main/java/org/apache/causeway/viewer/restfulobjects/client/ResponseDigester.java
+++ 
b/viewers/restfulobjects/client/src/main/java/org/apache/causeway/viewer/restfulobjects/client/ResponseDigester.java
@@ -28,7 +28,6 @@ import jakarta.ws.rs.core.Response;
 
 import com.fasterxml.jackson.core.JsonParseException;
 import com.fasterxml.jackson.databind.JsonMappingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
 
 import org.springframework.lang.Nullable;
 
@@ -36,6 +35,8 @@ import 
org.apache.causeway.applib.client.RepresentationTypeSimplifiedV2;
 import org.apache.causeway.commons.internal.base._Casts;
 import org.apache.causeway.commons.internal.base._Strings;
 import org.apache.causeway.commons.internal.exceptions._Exceptions;
+import org.apache.causeway.commons.io.DataSource;
+import org.apache.causeway.commons.io.JsonUtils;
 import org.apache.causeway.viewer.restfulobjects.applib.dtos.ScalarValueDtoV2;
 
 import lombok.RequiredArgsConstructor;
@@ -87,9 +88,13 @@ interface ResponseDigester {
         public <T> T readSingle(final Class<T> entityType, final Response 
response) {
             if(reprType.isValue()
                     || reprType.isValues()) {
-                val mapper = new ObjectMapper();
                 val jsonInput = response.readEntity(String.class);
-                val scalarValueDto = mapper.readValue(jsonInput, 
ScalarValueDtoV2.class);
+                val scalarValueDto =
+                    JsonUtils.tryRead(ScalarValueDtoV2.class,
+                            DataSource.ofStringUtf8(jsonInput),
+                            JsonUtils::jaxbAnnotationSupport)
+                    .ifFailureFail()
+                    .getValue().orElseThrow();
                 return extractValue(scalarValueDto);
             }
             return response.<T>readEntity(entityType);
@@ -100,12 +105,15 @@ interface ResponseDigester {
         public <T> List<T> readList(final Class<T> entityType, final 
GenericType<List<T>> genericType, final Response response) {
             if(reprType.isValues()
                     || reprType.isValue()) {
-                val mapper = new ObjectMapper();
+
                 val jsonInput = response.readEntity(String.class);
+
                 final List<ScalarValueDtoV2> scalarValueDtoList =
-                        mapper.readValue(
-                                jsonInput,
-                                
mapper.getTypeFactory().constructCollectionType(List.class, 
ScalarValueDtoV2.class));
+                    JsonUtils.tryReadAsList(ScalarValueDtoV2.class,
+                            DataSource.ofStringUtf8(jsonInput),
+                            JsonUtils::jaxbAnnotationSupport)
+                    .ifFailureFail()
+                    .getValue().orElseThrow();
 
                 final List<T> resultList = new 
ArrayList<>(scalarValueDtoList.size());
                 for(val valueBody : scalarValueDtoList) {
diff --git 
a/viewers/restfulobjects/client/src/main/java/org/apache/causeway/viewer/restfulobjects/client/RestfulClient.java
 
b/viewers/restfulobjects/client/src/main/java/org/apache/causeway/viewer/restfulobjects/client/RestfulClient.java
index 9988d8c7b0..972dd5d78c 100644
--- 
a/viewers/restfulobjects/client/src/main/java/org/apache/causeway/viewer/restfulobjects/client/RestfulClient.java
+++ 
b/viewers/restfulobjects/client/src/main/java/org/apache/causeway/viewer/restfulobjects/client/RestfulClient.java
@@ -21,6 +21,7 @@ package org.apache.causeway.viewer.restfulobjects.client;
 import java.net.URI;
 import java.util.List;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.function.UnaryOperator;
 
 import jakarta.ws.rs.client.Client;
@@ -33,12 +34,13 @@ import jakarta.ws.rs.core.UriBuilder;
 import org.apache.causeway.commons.collections.Can;
 import org.apache.causeway.commons.functional.Try;
 import org.apache.causeway.commons.internal.base._Strings;
-import org.apache.causeway.commons.internal.context._Context;
+import org.apache.causeway.commons.io.JsonUtils;
 import org.apache.causeway.viewer.restfulobjects.client.auth.BasicAuthFilter;
 import 
org.apache.causeway.viewer.restfulobjects.client.auth.BasicAuthFilter.Credentials;
 import 
org.apache.causeway.viewer.restfulobjects.client.log.ClientConversationLogger;
 
 import lombok.NonNull;
+import lombok.val;
 import lombok.extern.log4j.Log4j2;
 
 /**
@@ -111,7 +113,7 @@ public class RestfulClient implements AutoCloseable {
         final ClientBuilder clientBuilder = 
configRefiner.apply(ClientBuilder.newBuilder());
         this.client = clientBuilder.build();
 
-        registerDefaultJsonProvider();
+        
registerDefaultJsonProviderForJaxb(Optional.ofNullable(clientConfig.getJsonProviderForJaxb()));
         registerBasicAuthFilter();
         registerConversationFilters();
     }
@@ -180,15 +182,15 @@ public class RestfulClient implements AutoCloseable {
 
     // -- HELPER FILTER
 
-    private void registerDefaultJsonProvider() {
-        try {
-            Class<?> MOXyJsonProvider = 
_Context.loadClass("org.eclipse.persistence.jaxb.rs.MOXyJsonProvider");
-            client.register(MOXyJsonProvider);
-        } catch (Exception e) {
-            log.warn("This implementation of RestfulClient does require the 
class 'MOXyJsonProvider'"
-                    + " on the class-path."
-                    + " Are you missing a maven dependency?");
-        }
+    private void registerDefaultJsonProviderForJaxb(final Optional<Class<?>> 
jsonProviderForJaxbOverride) {
+
+        val jsonProviderForJaxb = jsonProviderForJaxbOverride
+                .orElseGet(JsonUtils::getPlatformDefaultJsonProviderForJaxb);
+
+        Try.run(()->client.register(jsonProviderForJaxb))
+        .ifFailure(cause->
+            log.error("Failed to register the JsonProviderForJaxb for the 
Restful Client to use."
+                    + " Are you missing a Maven dependency?", cause));
     }
 
     private void registerBasicAuthFilter() {
diff --git 
a/viewers/restfulobjects/client/src/main/java/org/apache/causeway/viewer/restfulobjects/client/RestfulClientConfig.java
 
b/viewers/restfulobjects/client/src/main/java/org/apache/causeway/viewer/restfulobjects/client/RestfulClientConfig.java
index c4caa327d9..c988318357 100644
--- 
a/viewers/restfulobjects/client/src/main/java/org/apache/causeway/viewer/restfulobjects/client/RestfulClientConfig.java
+++ 
b/viewers/restfulobjects/client/src/main/java/org/apache/causeway/viewer/restfulobjects/client/RestfulClientConfig.java
@@ -59,6 +59,12 @@ public class RestfulClientConfig {
     @XmlElement(name="restfulAuthPassword")
     private String restfulAuthPassword;
 
+    /**
+     * If left empty, the platform default is used.
+     */
+    @XmlElement(name="jsonProviderForJaxb")
+    private Class<?> jsonProviderForJaxb;
+
     /**
      * If enabled, logs conversation (request/response) details.
      */

Reply via email to