You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by da...@apache.org on 2025/07/28 12:53:39 UTC

(jackrabbit-oak) branch OAK-11801 created (now 76798a4d23)

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

daim pushed a change to branch OAK-11801
in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git


      at 76798a4d23 OAK-11801 : removed Guava's fluent iterable with Apache's

This branch includes the following new commits:

     new 76798a4d23 OAK-11801 : removed Guava's fluent iterable with Apache's

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



(jackrabbit-oak) 01/01: OAK-11801 : removed Guava's fluent iterable with Apache's

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

daim pushed a commit to branch OAK-11801
in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git

commit 76798a4d23d28a2df9e2bde2c4146df64fe232fb
Author: rishabhdaim <ri...@gmail.com>
AuthorDate: Mon Jul 28 18:23:21 2025 +0530

    OAK-11801 : removed Guava's fluent iterable with Apache's
---
 .../blob/datastore/SharedDataStoreUtils.java       | 26 +++++++++++++++++-----
 .../plugins/index/lucene/LucenePropertyIndex.java  |  9 ++++----
 oak-run-commons/pom.xml                            |  4 ++++
 .../indexer/document/NodeStateEntryTraverser.java  |  7 +++---
 .../document/mongo/MongoDocumentTraverser.java     |  4 ++--
 oak-run/pom.xml                                    |  4 ++++
 .../oak/plugins/tika/BinaryResourceProvider.java   |  4 ++--
 .../tika/CSVFileBinaryResourceProvider.java        |  4 ++--
 .../oak/plugins/tika/CSVFileGenerator.java         |  2 +-
 .../tika/NodeStoreBinaryResourceProvider.java      |  9 +++++---
 .../oak/plugins/tika/BinaryStatsTest.java          |  2 +-
 .../tika/CSVFileBinaryResourceProviderTest.java    | 18 +++++++++++++--
 .../tika/NodeStoreBinaryResourceProviderTest.java  |  3 ++-
 .../oak/plugins/tika/TextPopulatorTest.java        | 10 ++-------
 .../security/privilege/PrivilegeBitsProvider.java  |  4 ++--
 .../oak/composite/CompositeNodeBuilder.java        | 20 ++++++++---------
 .../oak/composite/CompositeNodeState.java          | 21 ++++++++---------
 17 files changed, 94 insertions(+), 57 deletions(-)

diff --git a/oak-blob-plugins/src/main/java/org/apache/jackrabbit/oak/plugins/blob/datastore/SharedDataStoreUtils.java b/oak-blob-plugins/src/main/java/org/apache/jackrabbit/oak/plugins/blob/datastore/SharedDataStoreUtils.java
index 184ed21696..bb19906d24 100644
--- a/oak-blob-plugins/src/main/java/org/apache/jackrabbit/oak/plugins/blob/datastore/SharedDataStoreUtils.java
+++ b/oak-blob-plugins/src/main/java/org/apache/jackrabbit/oak/plugins/blob/datastore/SharedDataStoreUtils.java
@@ -19,13 +19,15 @@ package org.apache.jackrabbit.oak.plugins.blob.datastore;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Set;
 import java.util.stream.Collectors;
 
-import org.apache.jackrabbit.guava.common.collect.FluentIterable;
+import org.apache.commons.collections4.FluentIterable;
 import org.apache.jackrabbit.core.data.DataRecord;
 import org.apache.jackrabbit.oak.commons.collections.SetUtils;
+import org.apache.jackrabbit.oak.commons.collections.StreamUtils;
 import org.apache.jackrabbit.oak.plugins.blob.SharedDataStore;
 import org.apache.jackrabbit.oak.spi.blob.BlobStore;
 
@@ -63,10 +65,24 @@ public class SharedDataStoreUtils {
      */
     public static Set<String> refsNotAvailableFromRepos(List<DataRecord> repos,
             List<DataRecord> refs) {
-        return SetUtils.difference(FluentIterable.from(repos)
-                .uniqueIndex(input -> SharedStoreRecordType.REPOSITORY.getIdFromName(input.getIdentifier().toString())).keySet(),
-                FluentIterable.from(refs)
-                        .index(input -> SharedStoreRecordType.REFERENCES.getIdFromName(input.getIdentifier().toString())).keySet());
+        return SetUtils.difference(
+                StreamUtils.toStream(
+                        FluentIterable.of(repos)).collect(
+                                Collectors.toMap(
+                                        input -> SharedStoreRecordType.REPOSITORY.getIdFromName(input.getIdentifier().toString()),
+                                        e -> e,
+                                        (oldValue, newValue) -> {
+                                            throw new IllegalArgumentException("Duplicate key found: " + SharedStoreRecordType.REPOSITORY.getIdFromName(newValue.getIdentifier().toString()));
+                                            },
+                                        LinkedHashMap::new))
+                        .keySet(),
+                StreamUtils.toStream(
+                        FluentIterable.of(refs)).collect(
+                                Collectors.groupingBy(
+                                        input -> SharedStoreRecordType.REFERENCES.getIdFromName(input.getIdentifier().toString()),
+                                        LinkedHashMap::new,
+                                        Collectors.toList()))
+                        .keySet());
     }
 
     /**
diff --git a/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java b/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java
index 9a9cc5278d..68f5e69e93 100644
--- a/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java
+++ b/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java
@@ -32,13 +32,14 @@ import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.function.Predicate;
 
+import org.apache.commons.collections4.FluentIterable;
 import org.apache.jackrabbit.guava.common.collect.AbstractIterator;
-import org.apache.jackrabbit.guava.common.collect.FluentIterable;
 import org.apache.jackrabbit.oak.api.PropertyValue;
 import org.apache.jackrabbit.oak.api.Type;
 import org.apache.jackrabbit.oak.commons.PathUtils;
@@ -1610,13 +1611,13 @@ public class LucenePropertyIndex extends FulltextIndex {
         FluentIterable<String> paths;
         if (pir != null) {
             Iterable<String> queryResult = lookup.query(plan.getFilter(), pir.propertyName, pir.pr);
-            paths = FluentIterable.from(queryResult)
+            paths = FluentIterable.of(queryResult)
                     .transform(path -> pr.isPathTransformed() ? pr.transformPath(path) : path)
-                    .filter(x -> x != null);
+                    .filter(Objects::nonNull);
         } else {
             Validate.checkState(pr.evaluateSyncNodeTypeRestriction()); //Either of property or nodetype should not be null
             Filter filter = plan.getFilter();
-            paths = FluentIterable.from(IterableUtils.chainedIterable(
+            paths = FluentIterable.of(IterableUtils.chainedIterable(
                     lookup.query(filter, JCR_PRIMARYTYPE, newName(filter.getPrimaryTypes())),
                     lookup.query(filter, JCR_MIXINTYPES, newName(filter.getMixinTypes()))));
         }
diff --git a/oak-run-commons/pom.xml b/oak-run-commons/pom.xml
index fae8a8bdcb..12223926cc 100644
--- a/oak-run-commons/pom.xml
+++ b/oak-run-commons/pom.xml
@@ -123,6 +123,10 @@
             <groupId>commons-io</groupId>
             <artifactId>commons-io</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-collections4</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.apache.felix</groupId>
             <artifactId>org.apache.felix.configadmin</artifactId>
diff --git a/oak-run-commons/src/main/java/org/apache/jackrabbit/oak/index/indexer/document/NodeStateEntryTraverser.java b/oak-run-commons/src/main/java/org/apache/jackrabbit/oak/index/indexer/document/NodeStateEntryTraverser.java
index 0d103d5ac3..e87698e785 100644
--- a/oak-run-commons/src/main/java/org/apache/jackrabbit/oak/index/indexer/document/NodeStateEntryTraverser.java
+++ b/oak-run-commons/src/main/java/org/apache/jackrabbit/oak/index/indexer/document/NodeStateEntryTraverser.java
@@ -19,7 +19,7 @@
 
 package org.apache.jackrabbit.oak.index.indexer.document;
 
-import org.apache.jackrabbit.guava.common.collect.FluentIterable;
+import org.apache.commons.collections4.FluentIterable;
 import org.apache.jackrabbit.oak.commons.collections.IterableUtils;
 import org.apache.jackrabbit.oak.commons.pio.Closer;
 import org.apache.jackrabbit.oak.plugins.document.Collection;
@@ -94,9 +94,8 @@ public class NodeStateEntryTraverser implements Iterable<NodeStateEntry>, Closea
 
     @SuppressWarnings("Guava")
     private Iterable<NodeStateEntry> getIncludedDocs() {
-        return FluentIterable.from(getDocsFilteredByPath())
-                .filter(doc -> includeDoc(doc))
-                .transformAndConcat(doc -> getEntries(doc));
+        return IterableUtils.chainedIterable(
+                FluentIterable.of(getDocsFilteredByPath()).filter(this::includeDoc).transform(this::getEntries));
     }
 
     private boolean includeDoc(NodeDocument doc) {
diff --git a/oak-run-commons/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentTraverser.java b/oak-run-commons/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentTraverser.java
index 076805666b..410e918031 100644
--- a/oak-run-commons/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentTraverser.java
+++ b/oak-run-commons/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentTraverser.java
@@ -22,7 +22,7 @@ package org.apache.jackrabbit.oak.plugins.document.mongo;
 import com.mongodb.BasicDBObject;
 import com.mongodb.ReadPreference;
 import com.mongodb.client.MongoCollection;
-import org.apache.jackrabbit.guava.common.collect.FluentIterable;
+import org.apache.commons.collections4.FluentIterable;
 import org.apache.jackrabbit.oak.commons.conditions.Validate;
 import org.apache.jackrabbit.oak.plugins.document.Collection;
 import org.apache.jackrabbit.oak.plugins.document.Document;
@@ -73,7 +73,7 @@ public class MongoDocumentTraverser {
         cursor = closeableCursor;
 
         @SuppressWarnings("Guava")
-        Iterable<T> result = FluentIterable.from(cursor)
+        Iterable<T> result = FluentIterable.of(cursor)
                 .filter(o -> filter.test((String) o.get(Document.ID)))
                 .transform(o -> {
                     T doc = mongoStore.convertFromDBObject(collection, o);
diff --git a/oak-run/pom.xml b/oak-run/pom.xml
index b8adfcc7db..0f653a6484 100644
--- a/oak-run/pom.xml
+++ b/oak-run/pom.xml
@@ -336,6 +336,10 @@
       <groupId>org.apache.commons</groupId>
       <artifactId>commons-lang3</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-collections4</artifactId>
+    </dependency>
     <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-text</artifactId>
diff --git a/oak-run/src/main/java/org/apache/jackrabbit/oak/plugins/tika/BinaryResourceProvider.java b/oak-run/src/main/java/org/apache/jackrabbit/oak/plugins/tika/BinaryResourceProvider.java
index 7a4081c7fd..51436afd65 100644
--- a/oak-run/src/main/java/org/apache/jackrabbit/oak/plugins/tika/BinaryResourceProvider.java
+++ b/oak-run/src/main/java/org/apache/jackrabbit/oak/plugins/tika/BinaryResourceProvider.java
@@ -19,9 +19,9 @@
 
 package org.apache.jackrabbit.oak.plugins.tika;
 
-import java.io.IOException;
+import org.apache.commons.collections4.FluentIterable;
 
-import org.apache.jackrabbit.guava.common.collect.FluentIterable;
+import java.io.IOException;
 
 /**
  * Provides an iterator for binaries present under given path
diff --git a/oak-run/src/main/java/org/apache/jackrabbit/oak/plugins/tika/CSVFileBinaryResourceProvider.java b/oak-run/src/main/java/org/apache/jackrabbit/oak/plugins/tika/CSVFileBinaryResourceProvider.java
index 40a153b389..3abd8fd91e 100644
--- a/oak-run/src/main/java/org/apache/jackrabbit/oak/plugins/tika/CSVFileBinaryResourceProvider.java
+++ b/oak-run/src/main/java/org/apache/jackrabbit/oak/plugins/tika/CSVFileBinaryResourceProvider.java
@@ -24,7 +24,7 @@ import java.io.IOException;
 import java.nio.charset.StandardCharsets;
 import java.util.function.Function;
 
-import org.apache.jackrabbit.guava.common.collect.FluentIterable;
+import org.apache.commons.collections4.FluentIterable;
 import org.apache.commons.csv.CSVFormat;
 import org.apache.commons.csv.CSVParser;
 import org.apache.commons.csv.CSVRecord;
@@ -72,7 +72,7 @@ class CSVFileBinaryResourceProvider implements BinaryResourceProvider, Closeable
     public FluentIterable<BinaryResource> getBinaries(final String path) throws IOException {
         CSVParser parser = CSVParser.parse(dataFile, StandardCharsets.UTF_8, FORMAT);
         closer.register(parser);
-        return FluentIterable.from(parser)
+        return FluentIterable.of(parser)
                 .transform(new RecordTransformer()::apply)
                 .filter(input -> input != null && PathUtils.isAncestor(path, input.getPath()));
     }
diff --git a/oak-run/src/main/java/org/apache/jackrabbit/oak/plugins/tika/CSVFileGenerator.java b/oak-run/src/main/java/org/apache/jackrabbit/oak/plugins/tika/CSVFileGenerator.java
index 93435cd6d2..7539e7d788 100644
--- a/oak-run/src/main/java/org/apache/jackrabbit/oak/plugins/tika/CSVFileGenerator.java
+++ b/oak-run/src/main/java/org/apache/jackrabbit/oak/plugins/tika/CSVFileGenerator.java
@@ -25,7 +25,7 @@ import java.io.FileWriter;
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
 
-import org.apache.jackrabbit.guava.common.collect.FluentIterable;
+import org.apache.commons.collections4.FluentIterable;
 import org.apache.commons.csv.CSVPrinter;
 import org.apache.jackrabbit.oak.commons.pio.Closer;
 import org.slf4j.Logger;
diff --git a/oak-run/src/main/java/org/apache/jackrabbit/oak/plugins/tika/NodeStoreBinaryResourceProvider.java b/oak-run/src/main/java/org/apache/jackrabbit/oak/plugins/tika/NodeStoreBinaryResourceProvider.java
index 5bba361659..30144ca739 100644
--- a/oak-run/src/main/java/org/apache/jackrabbit/oak/plugins/tika/NodeStoreBinaryResourceProvider.java
+++ b/oak-run/src/main/java/org/apache/jackrabbit/oak/plugins/tika/NodeStoreBinaryResourceProvider.java
@@ -18,7 +18,7 @@
  */
 package org.apache.jackrabbit.oak.plugins.tika;
 
-import org.apache.jackrabbit.guava.common.collect.FluentIterable;
+import org.apache.commons.collections4.FluentIterable;
 import org.apache.jackrabbit.guava.common.collect.TreeTraverser;
 import org.apache.jackrabbit.JcrConstants;
 import org.apache.jackrabbit.oak.api.Blob;
@@ -34,6 +34,7 @@ import org.slf4j.LoggerFactory;
 import static org.apache.jackrabbit.oak.plugins.tree.factories.TreeFactory.createReadOnlyTree;
 import static org.apache.jackrabbit.oak.spi.state.NodeStateUtils.getNode;
 
+import java.util.Objects;
 import java.util.function.Function;
 
 class NodeStoreBinaryResourceProvider implements BinaryResourceProvider {
@@ -47,10 +48,12 @@ class NodeStoreBinaryResourceProvider implements BinaryResourceProvider {
     }
 
     public FluentIterable<BinaryResource> getBinaries(String path) {
-        return new OakTreeTraverser()
+        // had to convert Guava's FluentIterable to Apache Commons Collections FluentIterable
+        // TODO once we remove preOrderTraversal() of Guava, we can use Apache FluentIterable directly
+        return FluentIterable.of(new OakTreeTraverser()
                 .preOrderTraversal(createReadOnlyTree(getNode(nodeStore.getRoot(), path)))
                 .transform(new TreeToBinarySource()::apply)
-                .filter(x -> x != null);
+                .filter(Objects::nonNull));
     }
 
     private class TreeToBinarySource implements Function<Tree, BinaryResource> {
diff --git a/oak-run/src/test/java/org/apache/jackrabbit/oak/plugins/tika/BinaryStatsTest.java b/oak-run/src/test/java/org/apache/jackrabbit/oak/plugins/tika/BinaryStatsTest.java
index 83a34bd6e0..08975b08ac 100644
--- a/oak-run/src/test/java/org/apache/jackrabbit/oak/plugins/tika/BinaryStatsTest.java
+++ b/oak-run/src/test/java/org/apache/jackrabbit/oak/plugins/tika/BinaryStatsTest.java
@@ -18,7 +18,7 @@
  */
 package org.apache.jackrabbit.oak.plugins.tika;
 
-import org.apache.jackrabbit.guava.common.collect.FluentIterable;
+import org.apache.commons.collections4.FluentIterable;
 import org.apache.jackrabbit.oak.plugins.tika.BinaryStats.MimeTypeStats;
 import org.junit.Assert;
 import org.junit.Test;
diff --git a/oak-run/src/test/java/org/apache/jackrabbit/oak/plugins/tika/CSVFileBinaryResourceProviderTest.java b/oak-run/src/test/java/org/apache/jackrabbit/oak/plugins/tika/CSVFileBinaryResourceProviderTest.java
index 65f2964daa..a12ee07fd7 100644
--- a/oak-run/src/test/java/org/apache/jackrabbit/oak/plugins/tika/CSVFileBinaryResourceProviderTest.java
+++ b/oak-run/src/test/java/org/apache/jackrabbit/oak/plugins/tika/CSVFileBinaryResourceProviderTest.java
@@ -21,8 +21,10 @@ package org.apache.jackrabbit.oak.plugins.tika;
 import java.io.File;
 import java.nio.file.Files;
 import java.util.Map;
+import java.util.stream.Collectors;
 
 import org.apache.commons.csv.CSVPrinter;
+import org.apache.jackrabbit.oak.commons.collections.StreamUtils;
 import org.apache.jackrabbit.oak.spi.blob.MemoryBlobStore;
 import org.junit.Rule;
 import org.junit.Test;
@@ -50,12 +52,24 @@ public class CSVFileBinaryResourceProviderTest {
 
         CSVFileBinaryResourceProvider provider = new CSVFileBinaryResourceProvider(dataFile, new MemoryBlobStore());
 
-        Map<String, BinaryResource> binaries = provider.getBinaries("/").uniqueIndex(BinarySourceMapper.BY_BLOBID::apply);
+        Map<String, BinaryResource> binaries = StreamUtils.toStream(provider.getBinaries("/")).collect(Collectors.toMap(
+                BinarySourceMapper.BY_BLOBID,
+                element -> element,
+                (oldValue, newValue) -> {
+                    throw new IllegalArgumentException("Duplicate key found: " + BinarySourceMapper.BY_BLOBID.apply(newValue));
+                } // This handles the duplicate key scenario similar to uniqueIndex
+        ));
         assertEquals(3, binaries.size());
         assertEquals("a", binaries.get("a").getBlobId());
         assertEquals("/a", binaries.get("a").getPath());
 
-        binaries = provider.getBinaries("/a").uniqueIndex(BinarySourceMapper.BY_BLOBID::apply);
+        binaries = StreamUtils.toStream(provider.getBinaries("/a")).collect(Collectors.toMap(
+                BinarySourceMapper.BY_BLOBID,
+                element -> element,
+                (oldValue, newValue) -> {
+                    throw new IllegalArgumentException("Duplicate key found: " + BinarySourceMapper.BY_BLOBID.apply(newValue));
+                } // This handles the duplicate key scenario similar to uniqueIndex
+        ));
         assertEquals(1, binaries.size());
 
         provider.close();
diff --git a/oak-run/src/test/java/org/apache/jackrabbit/oak/plugins/tika/NodeStoreBinaryResourceProviderTest.java b/oak-run/src/test/java/org/apache/jackrabbit/oak/plugins/tika/NodeStoreBinaryResourceProviderTest.java
index 2645bf3673..bba64bac2b 100644
--- a/oak-run/src/test/java/org/apache/jackrabbit/oak/plugins/tika/NodeStoreBinaryResourceProviderTest.java
+++ b/oak-run/src/test/java/org/apache/jackrabbit/oak/plugins/tika/NodeStoreBinaryResourceProviderTest.java
@@ -25,6 +25,7 @@ import java.io.IOException;
 
 import org.apache.jackrabbit.JcrConstants;
 import org.apache.jackrabbit.oak.api.Blob;
+import org.apache.jackrabbit.oak.commons.collections.IterableUtils;
 import org.apache.jackrabbit.oak.plugins.blob.BlobStoreBlob;
 import org.apache.jackrabbit.oak.plugins.memory.ArrayBasedBlob;
 import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeStore;
@@ -60,7 +61,7 @@ public class NodeStoreBinaryResourceProviderTest {
         assertEquals(2, extractor.getBinaries("/").size());
         assertEquals(1, extractor.getBinaries("/a2").size());
 
-        BinaryResource bs = extractor.getBinaries("/a2").first().get();
+        BinaryResource bs = IterableUtils.getFirst(extractor.getBinaries("/a2"), null);
         assertEquals("text/foo", bs.getMimeType());
         assertEquals("bar", bs.getEncoding());
         assertEquals("id2", bs.getBlobId());
diff --git a/oak-run/src/test/java/org/apache/jackrabbit/oak/plugins/tika/TextPopulatorTest.java b/oak-run/src/test/java/org/apache/jackrabbit/oak/plugins/tika/TextPopulatorTest.java
index 338b58e155..b2746eab77 100644
--- a/oak-run/src/test/java/org/apache/jackrabbit/oak/plugins/tika/TextPopulatorTest.java
+++ b/oak-run/src/test/java/org/apache/jackrabbit/oak/plugins/tika/TextPopulatorTest.java
@@ -18,7 +18,7 @@
  */
 package org.apache.jackrabbit.oak.plugins.tika;
 
-import org.apache.jackrabbit.guava.common.collect.FluentIterable;
+import org.apache.commons.collections4.FluentIterable;
 import org.apache.jackrabbit.oak.plugins.blob.datastore.TextWriter;
 import org.apache.jackrabbit.oak.plugins.index.lucene.FieldFactory;
 import org.apache.jackrabbit.oak.plugins.index.lucene.OakAnalyzer;
@@ -277,13 +277,7 @@ public class TextPopulatorTest {
 
         @Override
         public FluentIterable<BinaryResource> getBinaries(String path) {
-            return new FluentIterable<BinaryResource>() {
-                @NotNull
-                @Override
-                public Iterator<BinaryResource> iterator() {
-                    return binaries.iterator();
-                }
-            };
+            return FluentIterable.of(binaries);
         }
     }
 }
diff --git a/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/privilege/PrivilegeBitsProvider.java b/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/privilege/PrivilegeBitsProvider.java
index 6f4e095bbd..98f0585195 100644
--- a/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/privilege/PrivilegeBitsProvider.java
+++ b/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/privilege/PrivilegeBitsProvider.java
@@ -28,7 +28,7 @@ import java.util.function.Function;
 import javax.jcr.security.AccessControlException;
 import javax.jcr.security.Privilege;
 
-import org.apache.jackrabbit.guava.common.collect.FluentIterable;
+import org.apache.commons.collections4.FluentIterable;
 import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.api.Root;
 import org.apache.jackrabbit.oak.api.Tree;
@@ -263,7 +263,7 @@ public final class PrivilegeBitsProvider implements PrivilegeConstants {
 
     @NotNull
     private Iterable<String> extractAggregatedPrivileges(@NotNull Iterable<String> privilegeNames) {
-        return FluentIterable.from(privilegeNames).transformAndConcat(new ExtractAggregatedPrivileges()::apply);
+        return IterableUtils.chainedIterable(FluentIterable.of(privilegeNames).transform(new ExtractAggregatedPrivileges()::apply));
     }
 
     @NotNull
diff --git a/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositeNodeBuilder.java b/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositeNodeBuilder.java
index 997e95ac67..415385cf4d 100644
--- a/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositeNodeBuilder.java
+++ b/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositeNodeBuilder.java
@@ -16,13 +16,13 @@
  */
 package org.apache.jackrabbit.oak.composite;
 
-import org.apache.jackrabbit.guava.common.collect.FluentIterable;
+import org.apache.commons.collections4.FluentIterable;
 import org.apache.jackrabbit.oak.api.Blob;
 import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.api.Type;
 import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.commons.collections.IterableUtils;
 import org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState;
-import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeBuilder;
 import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 import org.slf4j.Logger;
@@ -175,24 +175,24 @@ class CompositeNodeBuilder implements NodeBuilder {
             return getWrappedNodeBuilder().getChildNodeCount(max);
         } else {
             // Count the children in each contributing store.
-            return accumulateChildSizes(FluentIterable.from(contributingStores)
-                    .transformAndConcat(mns -> {
+            return accumulateChildSizes(IterableUtils.chainedIterable(
+                    FluentIterable.of(contributingStores).transform(mns -> {
                         NodeBuilder node = nodeBuilders.get(mns);
                         if (node.getChildNodeCount(max) == MAX_VALUE) {
                             return singleton(STOP_COUNTING_CHILDREN);
                         } else {
-                            return FluentIterable.from(node.getChildNodeNames()).filter(e -> belongsToStore(mns, e));
+                            return FluentIterable.of(node.getChildNodeNames()).filter(e -> belongsToStore(mns, e));
                         }
-                    }), max);
+                    })), max);
         }
     }
 
     @Override
     public Iterable<String> getChildNodeNames() {
-        return FluentIterable.from(ctx.getContributingStoresForBuilders(getPath(), nodeBuilders))
-                .transformAndConcat(mns -> FluentIterable
-                        .from(nodeBuilders.get(mns).getChildNodeNames())
-                        .filter(e -> belongsToStore(mns, e)));
+        return IterableUtils.chainedIterable(
+                FluentIterable.of(ctx.getContributingStoresForBuilders(getPath(), nodeBuilders)).
+                        transform(mns -> FluentIterable.of(nodeBuilders.get(mns).getChildNodeNames()).
+                                filter(e -> belongsToStore(mns, e))));
     }
 
     @Override
diff --git a/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositeNodeState.java b/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositeNodeState.java
index a9397bbd7f..89f63a67ff 100644
--- a/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositeNodeState.java
+++ b/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositeNodeState.java
@@ -18,9 +18,10 @@
  */
 package org.apache.jackrabbit.oak.composite;
 
-import org.apache.jackrabbit.guava.common.collect.FluentIterable;
+import org.apache.commons.collections4.FluentIterable;
 import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.commons.collections.IterableUtils;
 import org.apache.jackrabbit.oak.plugins.memory.MemoryChildNodeEntry;
 import org.apache.jackrabbit.oak.spi.state.AbstractNodeState;
 import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
@@ -123,15 +124,15 @@ class CompositeNodeState extends AbstractNodeState {
             return getWrappedNodeState().getChildNodeCount(max);
         } else {
             // Count the children in each contributing store.
-            return accumulateChildSizes(FluentIterable.from(contributingStores)
-                    .transformAndConcat(mns -> {
+            return accumulateChildSizes(IterableUtils.chainedIterable(
+                    FluentIterable.of(contributingStores).transform(mns -> {
                         NodeState node = nodeStates.get(mns);
                         if (node.getChildNodeCount(max) == MAX_VALUE) {
                             return singleton(STOP_COUNTING_CHILDREN);
                         } else {
-                            return FluentIterable.from(node.getChildNodeNames()).filter(e -> belongsToStore(mns, e));
+                            return FluentIterable.of(node.getChildNodeNames()).filter(e -> belongsToStore(mns, e));
                         }
-                    }), max);
+                    })), max);
         }
     }
 
@@ -148,11 +149,11 @@ class CompositeNodeState extends AbstractNodeState {
 
     @Override
     public Iterable<? extends ChildNodeEntry> getChildNodeEntries() {
-        return FluentIterable.from(ctx.getContributingStoresForNodes(path, nodeStates))
-                .transformAndConcat(mns -> FluentIterable
-                        .from(nodeStates.get(mns).getChildNodeNames())
-                        .filter(n -> belongsToStore(mns, n)))
-                .transform(n -> new MemoryChildNodeEntry(n, getChildNode(n)));
+        return IterableUtils.chainedIterable(
+                FluentIterable.of(ctx.getContributingStoresForNodes(path, nodeStates)).
+                        transform(mns -> FluentIterable.of(nodeStates.get(mns).getChildNodeNames()).
+                                filter(n -> belongsToStore(mns, n)).
+                                transform(n -> new MemoryChildNodeEntry(n, getChildNode(n)))));
     }
 
     @Override