uschindler commented on code in PR #15864:
URL: https://github.com/apache/lucene/pull/15864#discussion_r2976139672


##########
lucene/core/src/java/org/apache/lucene/internal/tests/TestSecrets.java:
##########
@@ -31,26 +31,20 @@
  * initialized once on startup.
  */
 public final class TestSecrets {
-  static {
-    Consumer<Class<?>> ensureInitialized =
-        clazz -> {
-          try {
-            // A no-op forName here has a side-effect of ensuring the class is 
loaded and
-            // initialized.
-            // This only happens once. We could just leverage the JLS and 
invoke a static
-            // method (or a constructor) on the target class but the method 
below seems simpler.
-            // TODO: In Java 15 there's 
MethodHandles.lookup().ensureInitialized(clazz)
-            Class.forName(clazz.getName());
-          } catch (ClassNotFoundException e) {
-            throw new RuntimeException(e);
-          }
-        };
-
-    ensureInitialized.accept(ConcurrentMergeScheduler.class);
-    ensureInitialized.accept(SegmentReader.class);
-    ensureInitialized.accept(IndexWriter.class);
-    ensureInitialized.accept(FilterIndexInput.class);
-  }
+
+  private static final Consumer<Class<?>> ensureInitialized =

Review Comment:
   we can make a real private, static method here, the Lambda was only a 
workaround to not define a method just for the static initializer. As we need 
to call it lazily we can also have a method.



##########
lucene/core/src/java/org/apache/lucene/internal/tests/TestSecrets.java:
##########
@@ -71,60 +65,80 @@ private TestSecrets() {}
 
   /** Return the accessor to internal secrets for an {@link IndexReader}. */
   public static IndexPackageAccess getIndexPackageAccess() {
-    ensureCaller();
+    ensureCallerForGetter();
+    if (indexWriterAccess == null) {
+      ensureInitialized.accept(IndexWriter.class);
+    }
     return Objects.requireNonNull(indexPackageAccess);
   }
 
   /** Return the accessor to internal secrets for an {@link 
ConcurrentMergeScheduler}. */
   public static ConcurrentMergeSchedulerAccess 
getConcurrentMergeSchedulerAccess() {
-    ensureCaller();
+    ensureCallerForGetter();
+    if (cmsAccess == null) {
+      ensureInitialized.accept(ConcurrentMergeScheduler.class);
+    }
     return Objects.requireNonNull(cmsAccess);
   }
 
   /** Return the accessor to internal secrets for an {@link SegmentReader}. */
   public static SegmentReaderAccess getSegmentReaderAccess() {
-    ensureCaller();
+    ensureCallerForGetter();
+    if (segmentReaderAccess == null) {
+      ensureInitialized.accept(SegmentReader.class);
+    }
     return Objects.requireNonNull(segmentReaderAccess);
   }
 
   /** Return the accessor to internal secrets for an {@link IndexWriter}. */
   public static IndexWriterAccess getIndexWriterAccess() {
-    ensureCaller();
+    ensureCallerForGetter();
+    if (indexWriterAccess == null) {
+      ensureInitialized.accept(IndexWriter.class);
+    }
     return Objects.requireNonNull(indexWriterAccess);
   }
 
   /** Return the accessor to internal secrets for an {@link FilterIndexInput}. 
*/
   public static FilterIndexInputAccess getFilterInputIndexAccess() {
-    ensureCaller();
+    ensureCallerForGetter();
+    if (filterIndexInputAccess == null) {
+      ensureInitialized.accept(FilterIndexInput.class);
+    }
     return Objects.requireNonNull(filterIndexInputAccess);
   }
 
   /** For internal initialization only. */
   public static void setIndexWriterAccess(IndexWriterAccess indexWriterAccess) 
{
+    ensureCallerForSetter(IndexWriter.class);

Review Comment:
   That's nice that we check this now, but this change is unrelated, correct.
   
   Anyways, good to have it!



##########
lucene/core/src/java/org/apache/lucene/internal/tests/TestSecrets.java:
##########
@@ -136,7 +150,21 @@ private static void ensureNull(Object ob) {
     }
   }
 
-  private static void ensureCaller() {
+  private static void ensureCallerForSetter(Class<?> allowedCaller) {
+    final boolean validCaller =
+        StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE)

Review Comment:
   Change to something like:
   
   ```java
       final boolean validCaller =
           StackWalker.getInstance()
               .walk(
                   s ->
                       s.skip(2)
                           .limit(1)
                           .map(StackFrame::getClassName)
                           .allMatch(c -> Objects.equals(c, 
allowedCaller.getName())));
       if (!validCaller) {
         throw new UnsupportedOperationException(
             "The accessor can only be set by " + allowedCaller.getName() + 
".");
       }
   ```



##########
lucene/core/src/java/org/apache/lucene/internal/tests/TestSecrets.java:
##########
@@ -136,7 +150,21 @@ private static void ensureNull(Object ob) {
     }
   }
 
-  private static void ensureCaller() {
+  private static void ensureCallerForSetter(Class<?> allowedCaller) {
+    final boolean validCaller =
+        StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE)

Review Comment:
   We don't want to use `StackWalker.Option.RETAIN_CLASS_REFERENCE` in Lucene 
code, especially not in those code paths that are non-tests, because in Java 21 
SecurityManager is still active and requires higher privileges.
   
   Therefor remove this and better just comare classname as string (like below 
in the original code).



##########
lucene/core/src/test/org/apache/lucene/internal/tests/TestTestSecrets.java:
##########
@@ -37,4 +46,70 @@ public void testCannotSet() {
     expectThrows(AssertionError.class, () -> 
TestSecrets.setIndexPackageAccess(null));
     expectThrows(AssertionError.class, () -> 
TestSecrets.setSegmentReaderAccess(null));
   }
+
+  public void testDeadlock() throws Exception {

Review Comment:
   This test is fine, but I'd like to avoaid new tests spawning childs 
processes as much as possible. It is good to reproduce, but maybe @dweiss has 
an opinion.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to