You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@causeway.apache.org by ah...@apache.org on 2023/02/27 12:36:18 UTC

[causeway] branch master updated: CAUSEWAY-3304: DataSink/DataSource: fleshing out missing parts

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 68dc038666 CAUSEWAY-3304: DataSink/DataSource: fleshing out missing parts
68dc038666 is described below

commit 68dc0386663889c5c6f15670ccc8b1d1f8ad2f26
Author: Andi Huber <ah...@apache.org>
AuthorDate: Mon Feb 27 13:36:13 2023 +0100

    CAUSEWAY-3304: DataSink/DataSource: fleshing out missing parts
---
 .../commons/functional/ThrowingSupplier.java       | 137 +++++++++++++++++++++
 .../org/apache/causeway/commons/io/DataPeer.java   |  74 +++++++++++
 .../org/apache/causeway/commons/io/DataSink.java   |  68 +++++-----
 .../org/apache/causeway/commons/io/DataSource.java | 125 +++++++++++++++++--
 .../org/apache/causeway/commons/io/JaxbUtils.java  |   4 +-
 .../org/apache/causeway/commons/io/JsonUtils.java  |   4 +-
 .../org/apache/causeway/commons/io/YamlUtils.java  |   2 +-
 7 files changed, 371 insertions(+), 43 deletions(-)

diff --git a/commons/src/main/java/org/apache/causeway/commons/functional/ThrowingSupplier.java b/commons/src/main/java/org/apache/causeway/commons/functional/ThrowingSupplier.java
new file mode 100644
index 0000000000..5e18620b55
--- /dev/null
+++ b/commons/src/main/java/org/apache/causeway/commons/functional/ThrowingSupplier.java
@@ -0,0 +1,137 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.causeway.commons.functional;
+
+import java.util.function.BiFunction;
+import java.util.function.Supplier;
+
+/**
+ * A {@link Supplier} that allows invocation of code that throws a checked
+ * exception.
+ *
+ * @param <T> the type of results supplied by this supplier
+ * @apiNote this is a clone from <i>Spring's</i>
+ *     org.springframework.util.function.ThrowingSupplier (as was introduced with <i>Spring Framework v6</i>),
+ *     with version 3, the latter is used as a replacement and this interface is removed
+ */
+public interface ThrowingSupplier<T> extends Supplier<T> {
+
+    /**
+     * Gets a result, possibly throwing a checked exception.
+     * @return a result
+     * @throws Exception on error
+     */
+    T getWithException() throws Exception;
+
+    /**
+     * Default {@link Supplier#get()} that wraps any thrown checked exceptions
+     * (by default in a {@link RuntimeException}).
+     * @see java.util.function.Supplier#get()
+     */
+    @Override
+    default T get() {
+        return get(RuntimeException::new);
+    }
+
+    /**
+     * Gets a result, wrapping any thrown checked exceptions using the given
+     * {@code exceptionWrapper}.
+     * @param exceptionWrapper {@link BiFunction} that wraps the given message
+     * and checked exception into a runtime exception
+     * @return a result
+     */
+    default T get(final BiFunction<String, Exception, RuntimeException> exceptionWrapper) {
+        try {
+            return getWithException();
+        }
+        catch (RuntimeException ex) {
+            throw ex;
+        }
+        catch (Exception ex) {
+            throw exceptionWrapper.apply(ex.getMessage(), ex);
+        }
+    }
+
+    /**
+     * Return a new {@link ThrowingSupplier} where the {@link #get()} method
+     * wraps any thrown checked exceptions using the given
+     * {@code exceptionWrapper}.
+     * @param exceptionWrapper {@link BiFunction} that wraps the given message
+     * and checked exception into a runtime exception
+     * @return the replacement {@link ThrowingSupplier} instance
+     */
+    default ThrowingSupplier<T> throwing(final BiFunction<String, Exception, RuntimeException> exceptionWrapper) {
+        return new ThrowingSupplier<>() {
+
+            @Override
+            public T getWithException() throws Exception {
+                return ThrowingSupplier.this.getWithException();
+            }
+
+            @Override
+            public T get() {
+                return get(exceptionWrapper);
+            }
+
+        };
+    }
+
+    /**
+     * Lambda friendly convenience method that can be used to create a
+     * {@link ThrowingSupplier} where the {@link #get()} method wraps any checked
+     * exception thrown by the supplied lambda expression or method reference.
+     * <p>This method can be especially useful when working with method references.
+     * It allows you to easily convert a method that throws a checked exception
+     * into an instance compatible with a regular {@link Supplier}.
+     * <p>For example:
+     * <pre class="code">
+     * optional.orElseGet(ThrowingSupplier.of(Example::methodThatCanThrowCheckedException));
+     * </pre>
+     * @param <T> the type of results supplied by this supplier
+     * @param supplier the source supplier
+     * @return a new {@link ThrowingSupplier} instance
+     */
+    static <T> ThrowingSupplier<T> of(final ThrowingSupplier<T> supplier) {
+        return supplier;
+    }
+
+    /**
+     * Lambda friendly convenience method that can be used to create
+     * {@link ThrowingSupplier} where the {@link #get()} method wraps any
+     * thrown checked exceptions using the given {@code exceptionWrapper}.
+     * <p>This method can be especially useful when working with method references.
+     * It allows you to easily convert a method that throws a checked exception
+     * into an instance compatible with a regular {@link Supplier}.
+     * <p>For example:
+     * <pre class="code">
+     * optional.orElseGet(ThrowingSupplier.of(Example::methodThatCanThrowCheckedException, IllegalStateException::new));
+     * </pre>
+     * @param <T> the type of results supplied by this supplier
+     * @param supplier the source supplier
+     * @param exceptionWrapper the exception wrapper to use
+     * @return a new {@link ThrowingSupplier} instance
+     */
+    static <T> ThrowingSupplier<T> of(final ThrowingSupplier<T> supplier,
+            final BiFunction<String, Exception, RuntimeException> exceptionWrapper) {
+
+        return supplier.throwing(exceptionWrapper);
+    }
+
+}
+
diff --git a/commons/src/main/java/org/apache/causeway/commons/io/DataPeer.java b/commons/src/main/java/org/apache/causeway/commons/io/DataPeer.java
new file mode 100644
index 0000000000..3d8827ed8a
--- /dev/null
+++ b/commons/src/main/java/org/apache/causeway/commons/io/DataPeer.java
@@ -0,0 +1,74 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.causeway.commons.io;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.function.Function;
+
+import org.apache.causeway.commons.functional.ThrowingConsumer;
+import org.apache.causeway.commons.functional.Try;
+import org.apache.causeway.commons.internal.exceptions._Exceptions;
+
+import lombok.NonNull;
+import lombok.val;
+
+/**
+ * General purpose byte data peer that acts as source and sink at the same time.
+ *
+ * @since 2.0 {@index}
+ */
+public interface DataPeer extends DataSink, DataSource {
+
+    static DataPeer inMemory() {
+        return inMemory(32);
+    }
+
+    static DataPeer inMemory(final int initialBufferSize) {
+
+        val byteArrayHolder = new ArrayList<byte[]>(1);
+
+        return new DataPeer() {
+            @Override
+            public <T> Try<T> tryReadAll(@NonNull final Function<InputStream, Try<T>> consumingMapper) {
+                val in = DataSource.ofBytes(bytes());
+                return in.tryReadAll(consumingMapper);
+            }
+
+            @Override
+            public void writeAll(@NonNull final ThrowingConsumer<OutputStream> outputStreamConsumer) {
+                if(!byteArrayHolder.isEmpty()) {
+                    throw _Exceptions.illegalState("Cannot writeAll to an in-memory DataPeer, that was already written to.");
+                }
+                val out = DataSink.ofByteArrayConsumer(byteArrayHolder::add, initialBufferSize);
+                out.writeAll(outputStreamConsumer);
+            }
+
+            @Override
+            public byte[] bytes() {
+                return byteArrayHolder.isEmpty()
+                        ? new byte[0]
+                        : byteArrayHolder.get(0);
+            }
+
+        };
+    }
+
+}
diff --git a/commons/src/main/java/org/apache/causeway/commons/io/DataSink.java b/commons/src/main/java/org/apache/causeway/commons/io/DataSink.java
index a6eac0a622..642a1bd22e 100644
--- a/commons/src/main/java/org/apache/causeway/commons/io/DataSink.java
+++ b/commons/src/main/java/org/apache/causeway/commons/io/DataSink.java
@@ -25,12 +25,13 @@ import java.io.OutputStream;
 import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
 import java.util.function.Consumer;
-import java.util.function.Function;
-import java.util.function.Supplier;
 
+import org.apache.causeway.commons.functional.ThrowingConsumer;
+import org.apache.causeway.commons.functional.ThrowingSupplier;
 import org.apache.causeway.commons.functional.Try;
 
 import lombok.NonNull;
+import lombok.SneakyThrows;
 
 /**
  * General purpose writable byte data sink.
@@ -41,10 +42,10 @@ import lombok.NonNull;
 public interface DataSink {
 
     /**
-     * Re-throws any {@link Exception} from the mapped {@link Try},
-     * when the Try is a failure case.
+     * Offers this {@link DataSink}'s {@link OutputStream} to the caller,
+     * so it can write data to it.
      */
-    void writeAll(@NonNull Function<OutputStream, Try<Void>> producingMapper);
+    void writeAll(@NonNull final ThrowingConsumer<OutputStream> outputStreamConsumer);
 
     // -- FACTORIES
 
@@ -55,36 +56,36 @@ public interface DataSink {
         return consumingMapper -> {};
     }
 
-    static DataSink ofOutputStreamSupplier(final @NonNull Supplier<OutputStream> outputStreamSupplier) {
-        return outputConsumer ->
-            Try.call(()->{
+    static DataSink ofOutputStreamSupplier(final @NonNull ThrowingSupplier<OutputStream> outputStreamSupplier) {
+        return new DataSink() {
+            @Override @SneakyThrows
+            public void writeAll(final @NonNull ThrowingConsumer<OutputStream> outputStreamConsumer) {
                 try(final OutputStream os = outputStreamSupplier.get()) {
-                    return outputConsumer.apply(os);
+                    outputStreamConsumer.accept(os);
                 }
-            })
-            .ifFailureFail() // throw if any Exception outside the call to 'outputConsumer.apply(os)'
-            // unwrap the inner Try<Void>
-            .getValue().orElseThrow()
-            .ifFailureFail(); // throw if any Exception within the call to 'outputConsumer.apply(os)'
+            }
+        };
     }
 
-    static DataSink ofFile(final @NonNull File file) {
-        return ofOutputStreamSupplier(()->Try.call(()->new FileOutputStream(file)).ifFailureFail().getValue().orElseThrow());
-    }
-
-    static DataSink ofByteArrayConsumer(final @NonNull Consumer<byte[]> byteArrayConsumer) {
-        return outputConsumer ->
-            Try.call(()->{
-                try(final ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
-                    var innerTry = outputConsumer.apply(bos);
+    static DataSink ofByteArrayConsumer(final @NonNull ThrowingConsumer<byte[]> byteArrayConsumer, final int initalBufferSize) {
+        return new DataSink() {
+            @Override @SneakyThrows
+            public void writeAll(final @NonNull ThrowingConsumer<OutputStream> outputStreamConsumer) {
+                try(final ByteArrayOutputStream bos = new ByteArrayOutputStream(initalBufferSize)) {
+                    outputStreamConsumer.accept(bos);
                     byteArrayConsumer.accept(bos.toByteArray());
-                    return innerTry;
                 }
-            })
-            .ifFailureFail() // throw if any Exception outside the call to 'outputConsumer.apply(os)'
-            // unwrap the inner Try<Void>
-            .getValue().orElseThrow()
-            .ifFailureFail(); // throw if any Exception within the call to 'outputConsumer.apply(os)'
+            }
+        };
+    }
+
+    static DataSink ofByteArrayConsumer(final @NonNull ThrowingConsumer<byte[]> byteArrayConsumer) {
+        // using the default initalBufferSize from constructor ByteArrayOutputStream()
+        return ofByteArrayConsumer(byteArrayConsumer, 32);
+    }
+
+    static DataSink ofFile(final @NonNull File file) {
+        return ofOutputStreamSupplier(()->Try.call(()->new FileOutputStream(file)).valueAsNonNullElseFail());
     }
 
     static DataSink ofStringConsumer(final @NonNull Consumer<String> stringConsumer, final @NonNull Charset charset) {
@@ -99,6 +100,15 @@ public interface DataSink {
         return ofByteArrayConsumer(bytes->stringConsumer.append(new String(bytes, charset)));
     }
 
+    /**
+     * Example:
+     * <pre>
+     * var sb = new StringBuffer();
+     * var dataSink = DataSink.ofStringUtf8Consumer(sb);
+     * //... write to dataSink
+     * String result = sb.toString(); // read the buffer
+     * </pre>
+     */
     static DataSink ofStringUtf8Consumer(final @NonNull StringBuilder stringUtf8Consumer) {
         return ofStringConsumer(stringUtf8Consumer, StandardCharsets.UTF_8);
     }
diff --git a/commons/src/main/java/org/apache/causeway/commons/io/DataSource.java b/commons/src/main/java/org/apache/causeway/commons/io/DataSource.java
index b9ac147cae..ac56c99bff 100644
--- a/commons/src/main/java/org/apache/causeway/commons/io/DataSource.java
+++ b/commons/src/main/java/org/apache/causeway/commons/io/DataSource.java
@@ -18,6 +18,7 @@
  */
 package org.apache.causeway.commons.io;
 
+import java.awt.image.BufferedImage;
 import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.FileInputStream;
@@ -26,17 +27,23 @@ import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
 import java.util.function.Consumer;
 import java.util.function.Function;
-import java.util.function.Supplier;
+
+import javax.imageio.ImageIO;
 
 import org.springframework.lang.Nullable;
 
+import org.apache.causeway.commons.collections.Can;
 import org.apache.causeway.commons.functional.ThrowingConsumer;
 import org.apache.causeway.commons.functional.ThrowingFunction;
+import org.apache.causeway.commons.functional.ThrowingSupplier;
 import org.apache.causeway.commons.functional.Try;
+import org.apache.causeway.commons.internal.base._Bytes;
 import org.apache.causeway.commons.internal.base._NullSafe;
 import org.apache.causeway.commons.internal.base._Strings;
+import org.apache.causeway.commons.internal.base._Text;
 
 import lombok.NonNull;
+import lombok.val;
 
 /**
  * General purpose readable byte data source.
@@ -46,7 +53,7 @@ import lombok.NonNull;
 @FunctionalInterface
 public interface DataSource {
 
-    <T> Try<T> readAll(@NonNull Function<InputStream, Try<T>> consumingMapper);
+    <T> Try<T> tryReadAll(@NonNull Function<InputStream, Try<T>> consumingMapper);
 
     /**
      * Passes an {@link InputStream} to given {@link Function} for application.
@@ -55,7 +62,7 @@ public interface DataSource {
      *      if the InputStream is absent or not readable, the returned Try will hold the underlying {@link Exception}
      */
     default <T> Try<T> tryReadAndApply(final @NonNull ThrowingFunction<InputStream, T> inputStreamMapper) {
-        return readAll(inputStream->
+        return tryReadAll(inputStream->
             Try.call(()->inputStreamMapper.apply(inputStream)));
     }
 
@@ -65,10 +72,103 @@ public interface DataSource {
      *     if the InputStream is absent or not readable, the returned Try will hold the underlying {@link Exception}
      */
     default Try<Void> tryReadAndAccept(final @NonNull ThrowingConsumer<InputStream> inputStreamConsumer) {
-        return readAll(inputStream->
+        return tryReadAll(inputStream->
             Try.run(()->inputStreamConsumer.accept(inputStream)));
     }
 
+    // -- READ AS BYTES
+
+    /**
+     * Reads from this DataSource into a String using given charset encoding.
+     * <p>
+     * If the underlying {@link InputStream} is null a success {@link Try} is returned, containing a null value.
+     */
+    default Try<byte[]> tryReadAsBytes() {
+        return tryReadAndApply(inputStream->_Bytes.of(inputStream));
+    }
+
+    /**
+     * Shortcut for {@code tryReadAsBytes().valueAsNonNullElseFail()}.
+     */
+    default byte[] bytes() {
+        return tryReadAsBytes()
+                .valueAsNonNullElseFail();
+    }
+
+    // -- READ AS STRING
+
+    /**
+     * Reads from this DataSource into a String using given charset encoding.
+     * <p>
+     * If the underlying {@link InputStream} is null a success {@link Try} is returned, containing a null value.
+     */
+    default Try<String> tryReadAsString(final @NonNull Charset charset) {
+        return tryReadAndApply(inputStream->_Strings.ofBytes(_Bytes.of(inputStream), charset));
+    }
+
+    /**
+     * Reads from this DataSource into a String using UTF-8 encoding.
+     * <p>
+     * If the underlying {@link InputStream} is null a success {@link Try} is returned, containing a null value.
+     */
+    default Try<String> tryReadAsStringUtf8() {
+        return tryReadAsString(StandardCharsets.UTF_8);
+    }
+
+    // -- READ LINES
+
+    /**
+     * Reads from this DataSource all lines using given charset encoding.
+     * <p>
+     * If the underlying {@link InputStream} is null a success {@link Try} is returned, containing a null value.
+     */
+    default Try<Can<String>> tryReadAsLines(final @NonNull Charset charset) {
+        return tryReadAndApply(inputStream->_Text.readLines(inputStream, charset));
+    }
+
+    /**
+     * Reads from this DataSource all lines using UTF-8 encoding.
+     * <p>
+     * If the underlying {@link InputStream} is null a success {@link Try} is returned, containing a null value.
+     */
+    default Try<Can<String>> tryReadAsLinesUtf8() {
+        return tryReadAsLines(StandardCharsets.UTF_8);
+    }
+
+    // -- IMAGE DATA
+
+    default Try<BufferedImage> tryReadAsImage() {
+        return tryReadAndApply(ImageIO::read);
+    }
+
+    // -- PIPE
+
+    /**
+     * Acts as a pipe, reading from this {@link DataSource} and writing to given {@link DataSink},
+     * using given bufferSize for the underlying byte data junks.
+     * @return a success or failed {@link Try}, based on whether the write was successful or not
+     */
+    default Try<Void> tryReadAndWrite(final @NonNull DataSink dataSink, final int bufferSize) {
+        return tryReadAndAccept(inputStream->{
+            dataSink.writeAll(os->{
+                val buffer = new byte[bufferSize]; int n;
+                while((n = inputStream.read(buffer)) > -1) {
+                    os.write(buffer, 0, n);
+                }
+            });
+        });
+    }
+
+    /**
+     * Acts as a pipe, reading from this {@link DataSource} and writing to given {@link DataSink},
+     * using given bufferSize for the underlying byte data junks.
+     * <p>
+     * Throws if the write failed.
+     */
+    default void pipe(final @NonNull DataSink dataSink, final int bufferSize) {
+        tryReadAndWrite(dataSink, bufferSize).ifFailureFail();
+    }
+
     // -- FACTORIES
 
     /**
@@ -76,7 +176,7 @@ public interface DataSource {
      */
     static DataSource empty() {
         return new DataSource() {
-            @Override public <T> Try<T> readAll(final @NonNull Function<InputStream, Try<T>> consumingMapper) {
+            @Override public <T> Try<T> tryReadAll(final @NonNull Function<InputStream, Try<T>> consumingMapper) {
                 return Try.empty();
             }
         };
@@ -87,9 +187,9 @@ public interface DataSource {
      * @param inputStreamSupplier - required non-null
      * @throws NullPointerException - if the single argument is null
      */
-    static DataSource ofInputStreamSupplier(final @NonNull Supplier<InputStream> inputStreamSupplier) {
+    static DataSource ofInputStreamSupplier(final @NonNull ThrowingSupplier<InputStream> inputStreamSupplier) {
         return new DataSource() {
-            @Override public <T> Try<T> readAll(final @NonNull Function<InputStream, Try<T>> consumingMapper) {
+            @Override public <T> Try<T> tryReadAll(final @NonNull Function<InputStream, Try<T>> consumingMapper) {
                 return Try.call(()->{
                     try(final InputStream is = inputStreamSupplier.get()) {
                         return consumingMapper.apply(is);
@@ -114,6 +214,14 @@ public interface DataSource {
                 : ofInputStreamSupplier(()->cls.getResourceAsStream(resourcePath));
     }
 
+//    static DataSource ofTestResource(final Class<?> cls, final String path) {
+//        val prefix = "src/test/java/";
+//        val filePath = prefix + cls.getPackageName().replace('.', '/') + "/" + path;
+//        val file = new File(filePath);
+//        _Assert.assertTrue(file.exists(), ()->String.format("could not resolve resource '%s'", file.getAbsolutePath()));
+//        return ofFile(file);
+//    }
+
     /**
      * Creates a {@link DataSource} for given {@link File}.
      * If <code>null</code>, an 'empty' DataSource is returned.
@@ -123,8 +231,7 @@ public interface DataSource {
                 ? empty()
                 : ofInputStreamSupplier(
                     ()->Try.call(()->new FileInputStream(FileUtils.existingFileElseFail(file)))
-                        .ifFailureFail()
-                        .getValue().orElseThrow());
+                        .valueAsNonNullElseFail());
     }
 
     /**
diff --git a/commons/src/main/java/org/apache/causeway/commons/io/JaxbUtils.java b/commons/src/main/java/org/apache/causeway/commons/io/JaxbUtils.java
index 209606e2ab..193893e9df 100644
--- a/commons/src/main/java/org/apache/causeway/commons/io/JaxbUtils.java
+++ b/commons/src/main/java/org/apache/causeway/commons/io/JaxbUtils.java
@@ -192,7 +192,7 @@ public class JaxbUtils {
 
             @Override
             public T read(final DataSource source) {
-                return source.readAll((final InputStream is)->{
+                return source.tryReadAll((final InputStream is)->{
                     return Try.call(()->opts.unmarshal(jaxbContext, mappedType, is));
                 })
                 .ifFailureFail()
@@ -230,7 +230,7 @@ public class JaxbUtils {
             final @NonNull Class<T> mappedType,
             final @NonNull DataSource source,
             final JaxbUtils.JaxbCustomizer ... customizers) {
-        return source.readAll((final InputStream is)->{
+        return source.tryReadAll((final InputStream is)->{
             val opts = createOptions(customizers);
             return Try.call(()->opts.unmarshal(mappedType, is))
                     .mapFailure(cause->verboseException("unmarshalling XML", mappedType, cause));
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 5c5706562a..e8feb2e1bc 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
@@ -69,7 +69,7 @@ public class JsonUtils {
             final @NonNull Class<T> mappedType,
             final @NonNull DataSource source,
             final JsonUtils.JsonCustomizer ... customizers) {
-        return source.readAll((final InputStream is)->{
+        return source.tryReadAll((final InputStream is)->{
             return Try.call(()->createMapper(customizers).readValue(is, mappedType));
         });
     }
@@ -82,7 +82,7 @@ public class JsonUtils {
             final @NonNull Class<T> elementType,
             final @NonNull DataSource source,
             final JsonUtils.JsonCustomizer ... customizers) {
-        return source.readAll((final InputStream is)->{
+        return source.tryReadAll((final InputStream is)->{
             return Try.call(()->{
                 val mapper = createMapper(customizers);
                 val listFactory = mapper.getTypeFactory().constructCollectionType(List.class, elementType);
diff --git a/commons/src/main/java/org/apache/causeway/commons/io/YamlUtils.java b/commons/src/main/java/org/apache/causeway/commons/io/YamlUtils.java
index 6688a130cc..cc3f2da029 100644
--- a/commons/src/main/java/org/apache/causeway/commons/io/YamlUtils.java
+++ b/commons/src/main/java/org/apache/causeway/commons/io/YamlUtils.java
@@ -65,7 +65,7 @@ public class YamlUtils {
     public <T> Try<T> tryRead(
             final @NonNull Class<T> mappedType,
             final @NonNull DataSource source) {
-        return source.readAll((final InputStream is)->{
+        return source.tryReadAll((final InputStream is)->{
             return Try.call(()->createMapper(mappedType).load(is));
         });
     }