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

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

commit 519c19693829d95ba721b3ceb0727036115208a0
Author: Joerg Hoh <[email protected]>
AuthorDate: Fri Jul 18 16:05:17 2025 +0200

    OAK-11810 resolve UserMonitor lazily
---
 .../jackrabbit/oak/security/user/UserImporter.java | 31 ++++++++++++++++------
 .../user/UserImporterMembershipMonitoringTest.java |  7 +++--
 2 files changed, 26 insertions(+), 12 deletions(-)

diff --git 
a/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserImporter.java
 
b/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserImporter.java
index d711e583d9..7a4cc8dc67 100644
--- 
a/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserImporter.java
+++ 
b/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserImporter.java
@@ -77,6 +77,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.TreeSet;
+import java.util.function.Supplier;
 
 import static java.util.Objects.requireNonNull;
 import static java.util.concurrent.TimeUnit.NANOSECONDS;
@@ -169,7 +170,8 @@ class UserImporter implements ProtectedPropertyImporter, 
ProtectedNodeImporter,
      */
     private final Map<String, Principal> principals = new HashMap<>();
 
-    private UserMonitor userMonitor = UserMonitor.NOOP;
+    private UserMonitor userMonitor; // do not access directly, but only via 
the userMonitorSupplier
+    private Supplier<UserMonitor> userMonitorSupplier;
 
     UserImporter(ConfigurationParameters config) {
         importBehavior = UserUtil.getImportBehavior(config);
@@ -207,13 +209,26 @@ class UserImporter implements ProtectedPropertyImporter, 
ProtectedNodeImporter,
             return false;
         }
 
-        if (securityProvider instanceof WhiteboardAware) {
-            Whiteboard whiteboard = ((WhiteboardAware) 
securityProvider).getWhiteboard();
-            UserMonitor monitor = WhiteboardUtils.getService(whiteboard, 
UserMonitor.class);
-            if (monitor != null) {
-                userMonitor = monitor;
+        /*
+         * resolve the userMonitor lazily, as resolving that service via the 
OSGi service registry
+         * can be costly; this is often a redundant operation, because a 
UserImporter is typically much more
+         * frequent initialized than actually used.
+         */
+        userMonitorSupplier = () -> {
+            if (userMonitor == null) {
+                if (securityProvider instanceof WhiteboardAware) {
+                    Whiteboard whiteboard = ((WhiteboardAware) 
securityProvider).getWhiteboard();
+                    UserMonitor monitor = 
WhiteboardUtils.getService(whiteboard, UserMonitor.class);
+                    if (monitor != null) {
+                        userMonitor = monitor;
+                    }
+                }
+                if (userMonitor == null) { // always fall back to the NOOP 
version
+                    userMonitor = UserMonitor.NOOP;
+                }
             }
-        }
+            return userMonitor;
+        };
 
         initialized = true;
         return initialized;
@@ -647,7 +662,7 @@ class UserImporter implements ProtectedPropertyImporter, 
ProtectedNodeImporter,
                 memberContentIds.removeAll(failedContentIds);
 
                 userManager.onGroupUpdate(gr, false, true, memberContentIds, 
failedContentIds);
-                userMonitor.doneUpdateMembers(watch.elapsed(NANOSECONDS), 
totalSize, failedContentIds.size(), false);
+                
userMonitorSupplier.get().doneUpdateMembers(watch.elapsed(NANOSECONDS), 
totalSize, failedContentIds.size(), false);
             }
         }
 
diff --git 
a/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/UserImporterMembershipMonitoringTest.java
 
b/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/UserImporterMembershipMonitoringTest.java
index d3516e456d..7c4525e066 100644
--- 
a/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/UserImporterMembershipMonitoringTest.java
+++ 
b/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/UserImporterMembershipMonitoringTest.java
@@ -26,7 +26,7 @@ import org.junit.After;
 
 import java.lang.reflect.Field;
 
-import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertNull;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.Mockito.atLeastOnce;
@@ -84,11 +84,10 @@ public class UserImporterMembershipMonitoringTest extends 
UserImporterMembership
     boolean init(boolean createAction, Class<?>... extraInterfaces) throws 
Exception {
         boolean b = super.init(createAction, extraInterfaces);
 
-        // verify that the usermonitor has been properly initialized and 
replace it with the spied instance
+        // verify that the userMonitor is not initialized on init, but only on 
demand
         Field f = UserImporter.class.getDeclaredField("userMonitor");
         f.setAccessible(true);
-        assertSame(userMonitor, f.get(importer));
-
+        assertNull(f.get(importer));
         return b;
     }
 }
\ No newline at end of file

Reply via email to