You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by jp...@apache.org on 2022/01/10 14:42:53 UTC

[lucene] branch main updated: LUCENE-10283: Bump minimum required Java version to 17. (#579)

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

jpountz pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/lucene.git


The following commit(s) were added to refs/heads/main by this push:
     new 2ebc57a  LUCENE-10283: Bump minimum required Java version to 17. (#579)
2ebc57a is described below

commit 2ebc57a465fc584cf2242765898290a6c2f0f420
Author: Adrien Grand <jp...@gmail.com>
AuthorDate: Mon Jan 10 15:42:15 2022 +0100

    LUCENE-10283: Bump minimum required Java version to 17. (#579)
    
    Co-authored-by: Dawid Weiss <da...@carrotsearch.com>
---
 .github/workflows/gradle-precommit.yml             |  4 +-
 README.md                                          |  6 +-
 build.gradle                                       |  2 +-
 buildSrc/scriptDepVersions.gradle                  |  2 +-
 gradle/validation/spotless.gradle                  |  2 +-
 lucene/CHANGES.txt                                 |  3 +
 lucene/SYSTEM_REQUIREMENTS.md                      |  4 +-
 .../org/apache/lucene/store/MMapDirectory.java     | 29 ++++----
 .../org/apache/lucene/util/NamedThreadFactory.java | 14 +++-
 .../org/apache/lucene/util/RamUsageEstimator.java  | 14 +++-
 .../apache/lucene/util/fst/PositiveIntOutputs.java |  6 +-
 .../apache/lucene/analysis/TestCharArraySet.java   |  8 +--
 .../misc/store/HardlinkCopyDirectoryWrapper.java   | 49 ++++++++------
 .../misc/util/fst/UpToTwoPositiveIntOutputs.java   |  6 +-
 .../apache/lucene/tests/util/LuceneTestCase.java   |  2 +
 .../apache/lucene/tests/util/RamUsageTester.java   | 78 ++++++++++++----------
 .../lucene/tests/util/TestSecurityManager.java     |  3 +
 17 files changed, 130 insertions(+), 102 deletions(-)

diff --git a/.github/workflows/gradle-precommit.yml b/.github/workflows/gradle-precommit.yml
index 13b4b64..33474ba 100644
--- a/.github/workflows/gradle-precommit.yml
+++ b/.github/workflows/gradle-precommit.yml
@@ -21,7 +21,7 @@ jobs:
         # Operating systems to run on.
         os: [ubuntu-latest]
         # Test JVMs.
-        java: [ '11' ]
+        java: [ '17' ]
 
     steps:
     - uses: actions/checkout@v2
@@ -65,7 +65,7 @@ jobs:
         # macos-latest: a tad slower than ubuntu and pretty much the same (?) so leaving out.
         os: [ubuntu-latest]
         # Test JVMs.
-        java: [ '11' ]
+        java: [ '17' ]
 
     steps:
     - uses: actions/checkout@v2
diff --git a/README.md b/README.md
index 260bcbc..f07d999 100644
--- a/README.md
+++ b/README.md
@@ -39,16 +39,16 @@ comprehensive documentation, visit:
 
 ### Basic steps:
   
-  0. Install OpenJDK 11 (or greater).
+  0. Install OpenJDK 17 (or greater).
   1. Clone Lucene's git repository (or download the source distribution).
   2. Run gradle launcher script (`gradlew`).
 
-### Step 0) Set up your development environment (OpenJDK 11 or greater)
+### Step 0) Set up your development environment (OpenJDK 17 or greater)
 
 We'll assume that you know how to get and set up the JDK - if you
 don't, then we suggest starting at https://jdk.java.net/ and learning
 more about Java, before returning to this README. Lucene runs with
-Java 11 or later. 
+Java 17 or later. 
 
 Lucene uses [Gradle](https://gradle.org/) for build control. Gradle is itself Java-based
 and may be incompatible with newer Java versions; you can still build and test 
diff --git a/build.gradle b/build.gradle
index 79a90cb..23a3b18 100644
--- a/build.gradle
+++ b/build.gradle
@@ -72,7 +72,7 @@ ext {
   }
 
   // Minimum Java version required to compile and run Lucene.
-  minJavaVersion = JavaVersion.VERSION_11
+  minJavaVersion = JavaVersion.VERSION_17
 
   // snapshot build marker used in scripts.
   snapshotBuild = version.contains("SNAPSHOT")
diff --git a/buildSrc/scriptDepVersions.gradle b/buildSrc/scriptDepVersions.gradle
index 19533b3..12fda6b 100644
--- a/buildSrc/scriptDepVersions.gradle
+++ b/buildSrc/scriptDepVersions.gradle
@@ -23,7 +23,7 @@ ext {
   scriptDepVersions = [
       "apache-rat": "0.11",
       "commons-codec": "1.13",
-      "ecj": "3.27.0",
+      "ecj": "3.28.0",
       "flexmark": "0.61.24",
       "javacc": "7.0.4",
       "jflex": "1.8.2",
diff --git a/gradle/validation/spotless.gradle b/gradle/validation/spotless.gradle
index be2a6d9..0ee79cc 100644
--- a/gradle/validation/spotless.gradle
+++ b/gradle/validation/spotless.gradle
@@ -37,7 +37,7 @@ configure(project(":lucene").subprojects) { prj ->
 
         lineEndings 'UNIX'
         endWithNewline()
-        googleJavaFormat('1.11.0')
+        googleJavaFormat('1.13.0')
 
         // Apply to all Java sources
         target "src/**/*.java"
diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index ea2c664..01137e6 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -32,6 +32,9 @@ Bug Fixes
 Other
 ---------------------
 
+* LUCENE-10283: The minimum required Java version was bumped from 11 to 17.
+  (Adrien Grand, Uwe Schindler, Dawid Weiss, Robert Muir)
+
 * LUCENE-10253: The @BadApple annotation has been removed from the test
   framework. (Adrien Grand)
 
diff --git a/lucene/SYSTEM_REQUIREMENTS.md b/lucene/SYSTEM_REQUIREMENTS.md
index bafcedb..b158d16 100644
--- a/lucene/SYSTEM_REQUIREMENTS.md
+++ b/lucene/SYSTEM_REQUIREMENTS.md
@@ -17,11 +17,11 @@
 
 # System Requirements 
 
-Apache Lucene runs on Java 11 or greater.
+Apache Lucene runs on Java 17 or greater.
 
 It is also recommended to always use the latest update version of your
 Java VM, because bugs may affect Lucene. An overview of known JVM bugs
-can be found on http://wiki.apache.org/lucene-java/JavaBugs
+can be found on https://cwiki.apache.org/confluence/display/LUCENE/JavaBugs
 
 With all Java versions it is strongly recommended to not use experimental
 `-XX` JVM options.
diff --git a/lucene/core/src/java/org/apache/lucene/store/MMapDirectory.java b/lucene/core/src/java/org/apache/lucene/store/MMapDirectory.java
index 5c20055..f31a3a1 100644
--- a/lucene/core/src/java/org/apache/lucene/store/MMapDirectory.java
+++ b/lucene/core/src/java/org/apache/lucene/store/MMapDirectory.java
@@ -334,8 +334,7 @@ public class MMapDirectory extends FSDirectory {
   private static final BufferCleaner CLEANER;
 
   static {
-    final Object hack =
-        AccessController.doPrivileged((PrivilegedAction<Object>) MMapDirectory::unmapHackImpl);
+    final Object hack = doPrivileged(MMapDirectory::unmapHackImpl);
     if (hack instanceof BufferCleaner) {
       CLEANER = (BufferCleaner) hack;
       UNMAP_SUPPORTED = true;
@@ -348,6 +347,13 @@ public class MMapDirectory extends FSDirectory {
     }
   }
 
+  // Extracted to a method to be able to apply the SuppressForbidden annotation
+  @SuppressWarnings("removal")
+  @SuppressForbidden(reason = "security manager")
+  private static <T> T doPrivileged(PrivilegedAction<T> action) {
+    return AccessController.doPrivileged(action);
+  }
+
   @SuppressForbidden(reason = "Needs access to sun.misc.Unsafe to enable hack")
   private static Object unmapHackImpl() {
     final Lookup lookup = lookup();
@@ -390,16 +396,15 @@ public class MMapDirectory extends FSDirectory {
         throw new IllegalArgumentException("unmapping only works with direct buffers");
       }
       final Throwable error =
-          AccessController.doPrivileged(
-              (PrivilegedAction<Throwable>)
-                  () -> {
-                    try {
-                      unmapper.invokeExact(buffer);
-                      return null;
-                    } catch (Throwable t) {
-                      return t;
-                    }
-                  });
+          doPrivileged(
+              () -> {
+                try {
+                  unmapper.invokeExact(buffer);
+                  return null;
+                } catch (Throwable t) {
+                  return t;
+                }
+              });
       if (error != null) {
         throw new IOException("Unable to unmap the mapped buffer: " + resourceDescription, error);
       }
diff --git a/lucene/core/src/java/org/apache/lucene/util/NamedThreadFactory.java b/lucene/core/src/java/org/apache/lucene/util/NamedThreadFactory.java
index 2d79c45..99d2c25 100644
--- a/lucene/core/src/java/org/apache/lucene/util/NamedThreadFactory.java
+++ b/lucene/core/src/java/org/apache/lucene/util/NamedThreadFactory.java
@@ -39,8 +39,7 @@ public class NamedThreadFactory implements ThreadFactory {
    * @param threadNamePrefix the name prefix assigned to each thread created.
    */
   public NamedThreadFactory(String threadNamePrefix) {
-    final SecurityManager s = System.getSecurityManager();
-    group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
+    group = getThreadGroup();
     this.threadNamePrefix =
         String.format(
             Locale.ROOT,
@@ -49,6 +48,17 @@ public class NamedThreadFactory implements ThreadFactory {
             threadPoolNumber.getAndIncrement());
   }
 
+  @SuppressWarnings("removal")
+  @SuppressForbidden(reason = "security manager")
+  private static ThreadGroup getThreadGroup() {
+    final SecurityManager s = System.getSecurityManager();
+    if (s != null) {
+      return s.getThreadGroup();
+    } else {
+      return Thread.currentThread().getThreadGroup();
+    }
+  }
+
   private static String checkPrefix(String prefix) {
     return prefix == null || prefix.length() == 0 ? "Lucene" : prefix;
   }
diff --git a/lucene/core/src/java/org/apache/lucene/util/RamUsageEstimator.java b/lucene/core/src/java/org/apache/lucene/util/RamUsageEstimator.java
index c7f225b..e28e2a7 100644
--- a/lucene/core/src/java/org/apache/lucene/util/RamUsageEstimator.java
+++ b/lucene/core/src/java/org/apache/lucene/util/RamUsageEstimator.java
@@ -584,9 +584,10 @@ public final class RamUsageEstimator {
       final Class<?> target = clazz;
       final Field[] fields;
       try {
-        fields =
-            AccessController.doPrivileged((PrivilegedAction<Field[]>) target::getDeclaredFields);
-      } catch (AccessControlException e) {
+        fields = doPrivileged((PrivilegedAction<Field[]>) target::getDeclaredFields);
+      } catch (
+          @SuppressWarnings("removal")
+          AccessControlException e) {
         throw new RuntimeException("Can't access fields of class: " + target, e);
       }
 
@@ -599,6 +600,13 @@ public final class RamUsageEstimator {
     return alignObjectSize(size);
   }
 
+  // Extracted to a method to give the SuppressForbidden annotation the smallest possible scope
+  @SuppressWarnings("removal")
+  @SuppressForbidden(reason = "security manager")
+  private static <T> T doPrivileged(PrivilegedAction<T> action) {
+    return AccessController.doPrivileged(action);
+  }
+
   /** Return shallow size of any <code>array</code>. */
   private static long shallowSizeOfArray(Object array) {
     long size = NUM_BYTES_ARRAY_HEADER;
diff --git a/lucene/core/src/java/org/apache/lucene/util/fst/PositiveIntOutputs.java b/lucene/core/src/java/org/apache/lucene/util/fst/PositiveIntOutputs.java
index 7e4fea6..a878cb4 100644
--- a/lucene/core/src/java/org/apache/lucene/util/fst/PositiveIntOutputs.java
+++ b/lucene/core/src/java/org/apache/lucene/util/fst/PositiveIntOutputs.java
@@ -20,19 +20,15 @@ import java.io.IOException;
 import org.apache.lucene.store.DataInput;
 import org.apache.lucene.store.DataOutput;
 import org.apache.lucene.util.RamUsageEstimator;
-import org.apache.lucene.util.SuppressForbidden;
 
 /**
  * An FST {@link Outputs} implementation where each output is a non-negative long value.
  *
  * @lucene.experimental
  */
-@SuppressForbidden(reason = "Uses a Long instance as a marker")
 public final class PositiveIntOutputs extends Outputs<Long> {
 
-  // Ignore the deprecated constructor. We do want a unique object here.
-  @SuppressWarnings({"all"})
-  private static final Long NO_OUTPUT = new Long(0);
+  private static final Long NO_OUTPUT = 0L;
 
   private static final PositiveIntOutputs singleton = new PositiveIntOutputs();
 
diff --git a/lucene/core/src/test/org/apache/lucene/analysis/TestCharArraySet.java b/lucene/core/src/test/org/apache/lucene/analysis/TestCharArraySet.java
index b25b4e8..b668be0 100644
--- a/lucene/core/src/test/org/apache/lucene/analysis/TestCharArraySet.java
+++ b/lucene/core/src/test/org/apache/lucene/analysis/TestCharArraySet.java
@@ -56,20 +56,14 @@ public class TestCharArraySet extends LuceneTestCase {
   @SuppressForbidden(reason = "Explicitly checking new Integers")
   public void testObjectContains() {
     CharArraySet set = new CharArraySet(10, true);
-    Integer val = Integer.valueOf(1);
-    @SuppressWarnings("all")
-    Integer val1 = new Integer(1);
-    // Verify explicitly the case of different Integer instances
-    assertNotSame(val, val1);
+    Integer val = 1;
     set.add(val);
     assertTrue(set.contains(val));
-    assertTrue(set.contains(val1)); // another integer
     assertTrue(set.contains("1"));
     assertTrue(set.contains(new char[] {'1'}));
     // test unmodifiable
     set = CharArraySet.unmodifiableSet(set);
     assertTrue(set.contains(val));
-    assertTrue(set.contains(val1)); // another integer
     assertTrue(set.contains("1"));
     assertTrue(set.contains(new char[] {'1'}));
   }
diff --git a/lucene/misc/src/java/org/apache/lucene/misc/store/HardlinkCopyDirectoryWrapper.java b/lucene/misc/src/java/org/apache/lucene/misc/store/HardlinkCopyDirectoryWrapper.java
index 3361c26..fd83daa 100644
--- a/lucene/misc/src/java/org/apache/lucene/misc/store/HardlinkCopyDirectoryWrapper.java
+++ b/lucene/misc/src/java/org/apache/lucene/misc/store/HardlinkCopyDirectoryWrapper.java
@@ -29,6 +29,7 @@ import org.apache.lucene.store.Directory;
 import org.apache.lucene.store.FSDirectory;
 import org.apache.lucene.store.FilterDirectory;
 import org.apache.lucene.store.IOContext;
+import org.apache.lucene.util.SuppressForbidden;
 
 /**
  * This directory wrapper overrides {@link Directory#copyFrom(Directory, String, String, IOContext)}
@@ -66,27 +67,26 @@ public final class HardlinkCopyDirectoryWrapper extends FilterDirectory {
         // only try hardlinks if we have permission to access the files
         // if not super.copyFrom() will give us the right exceptions
         suppressedException =
-            AccessController.doPrivileged(
-                (PrivilegedAction<Exception>)
-                    () -> {
-                      try {
-                        Files.createLink(toPath.resolve(destFile), fromPath.resolve(srcFile));
-                      } catch (FileNotFoundException
-                          | NoSuchFileException
-                          | FileAlreadyExistsException ex) {
-                        return ex; // in these cases we bubble up since it's a true error condition.
-                      } catch (IOException
-                          // if the FS doesn't support hard-links
-                          | UnsupportedOperationException
-                          // we don't have permission to use hard-links just fall back to byte copy
-                          | SecurityException ex) {
-                        // hard-links are not supported or the files are on different filesystems
-                        // we could go deeper and check if their filesstores are the same and opt
-                        // out earlier but for now we just fall back to normal file-copy
-                        return ex;
-                      }
-                      return null;
-                    });
+            doPrivileged(
+                () -> {
+                  try {
+                    Files.createLink(toPath.resolve(destFile), fromPath.resolve(srcFile));
+                  } catch (FileNotFoundException
+                      | NoSuchFileException
+                      | FileAlreadyExistsException ex) {
+                    return ex; // in these cases we bubble up since it's a true error condition.
+                  } catch (IOException
+                      // if the FS doesn't support hard-links
+                      | UnsupportedOperationException
+                      // we don't have permission to use hard-links just fall back to byte copy
+                      | SecurityException ex) {
+                    // hard-links are not supported or the files are on different filesystems
+                    // we could go deeper and check if their filesstores are the same and opt
+                    // out earlier but for now we just fall back to normal file-copy
+                    return ex;
+                  }
+                  return null;
+                });
         tryCopy = suppressedException != null;
       }
     }
@@ -101,4 +101,11 @@ public final class HardlinkCopyDirectoryWrapper extends FilterDirectory {
       }
     }
   }
+
+  // Extracted to a method to give the SuppressForbidden annotation the smallest possible scope
+  @SuppressWarnings("removal")
+  @SuppressForbidden(reason = "security manager")
+  private static <T> T doPrivileged(PrivilegedAction<T> action) {
+    return AccessController.doPrivileged(action);
+  }
 }
diff --git a/lucene/misc/src/java/org/apache/lucene/misc/util/fst/UpToTwoPositiveIntOutputs.java b/lucene/misc/src/java/org/apache/lucene/misc/util/fst/UpToTwoPositiveIntOutputs.java
index b70c5c8..c35a03d 100644
--- a/lucene/misc/src/java/org/apache/lucene/misc/util/fst/UpToTwoPositiveIntOutputs.java
+++ b/lucene/misc/src/java/org/apache/lucene/misc/util/fst/UpToTwoPositiveIntOutputs.java
@@ -20,7 +20,6 @@ import java.io.IOException;
 import org.apache.lucene.store.DataInput;
 import org.apache.lucene.store.DataOutput;
 import org.apache.lucene.util.RamUsageEstimator;
-import org.apache.lucene.util.SuppressForbidden;
 import org.apache.lucene.util.fst.FSTCompiler;
 import org.apache.lucene.util.fst.Outputs;
 
@@ -40,7 +39,6 @@ import org.apache.lucene.util.fst.Outputs;
  *
  * @lucene.experimental
  */
-@SuppressForbidden(reason = "Uses a Long instance as a marker")
 public final class UpToTwoPositiveIntOutputs extends Outputs<Object> {
 
   /** Holds two long outputs. */
@@ -76,9 +74,7 @@ public final class UpToTwoPositiveIntOutputs extends Outputs<Object> {
     }
   }
 
-  // Ignore the deprecated constructor. We do want a unique object here.
-  @SuppressWarnings({"all"})
-  private static final Long NO_OUTPUT = new Long(0);
+  private static final Long NO_OUTPUT = 0L;
 
   private final boolean doShare;
 
diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java
index 48032cd..16b5b52 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java
@@ -3103,6 +3103,8 @@ public abstract class LuceneTestCase extends Assert {
    * execution. If enabled, it needs the following {@link SecurityPermission}: {@code
    * "createAccessControlContext"}
    */
+  @SuppressForbidden(reason = "security manager")
+  @SuppressWarnings("removal")
   public static <T> T runWithRestrictedPermissions(
       PrivilegedExceptionAction<T> action, Permission... permissions) throws Exception {
     assumeTrue(
diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/RamUsageTester.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/RamUsageTester.java
index 870509d..5248242 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/RamUsageTester.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/RamUsageTester.java
@@ -323,46 +323,50 @@ public final class RamUsageTester {
   /** Create a cached information about shallow size and reference fields for a given class. */
   @SuppressForbidden(reason = "We need to access private fields of measured objects.")
   private static ClassCache createCacheEntry(final Class<?> clazz) {
-    return AccessController.doPrivileged(
-        (PrivilegedAction<ClassCache>)
-            () -> {
-              ClassCache cachedInfo;
-              long shallowInstanceSize = RamUsageEstimator.NUM_BYTES_OBJECT_HEADER;
-              final ArrayList<Field> referenceFields = new ArrayList<>(32);
-              for (Class<?> c = clazz; c != null; c = c.getSuperclass()) {
-                if (c == Class.class) {
-                  // prevent inspection of Class' fields, throws SecurityException in Java 9!
-                  continue;
-                }
-                final Field[] fields = c.getDeclaredFields();
-                for (final Field f : fields) {
-                  if (!Modifier.isStatic(f.getModifiers())) {
-                    shallowInstanceSize = RamUsageEstimator.adjustForField(shallowInstanceSize, f);
-
-                    if (!f.getType().isPrimitive()) {
-                      try {
-                        f.setAccessible(true);
-                        referenceFields.add(f);
-                      } catch (RuntimeException re) {
-                        throw new RuntimeException(
-                            String.format(
-                                Locale.ROOT,
-                                "Can't access field '%s' of class '%s' for RAM estimation.",
-                                f.getName(),
-                                clazz.getName()),
-                            re);
+    @SuppressWarnings("removal")
+    ClassCache classCache =
+        AccessController.doPrivileged(
+            (PrivilegedAction<ClassCache>)
+                () -> {
+                  ClassCache cachedInfo;
+                  long shallowInstanceSize = RamUsageEstimator.NUM_BYTES_OBJECT_HEADER;
+                  final ArrayList<Field> referenceFields = new ArrayList<>(32);
+                  for (Class<?> c = clazz; c != null; c = c.getSuperclass()) {
+                    if (c == Class.class) {
+                      // prevent inspection of Class' fields, throws SecurityException in Java 9!
+                      continue;
+                    }
+                    final Field[] fields = c.getDeclaredFields();
+                    for (final Field f : fields) {
+                      if (!Modifier.isStatic(f.getModifiers())) {
+                        shallowInstanceSize =
+                            RamUsageEstimator.adjustForField(shallowInstanceSize, f);
+
+                        if (!f.getType().isPrimitive()) {
+                          try {
+                            f.setAccessible(true);
+                            referenceFields.add(f);
+                          } catch (RuntimeException re) {
+                            throw new RuntimeException(
+                                String.format(
+                                    Locale.ROOT,
+                                    "Can't access field '%s' of class '%s' for RAM estimation.",
+                                    f.getName(),
+                                    clazz.getName()),
+                                re);
+                          }
+                        }
                       }
                     }
                   }
-                }
-              }
-
-              cachedInfo =
-                  new ClassCache(
-                      RamUsageEstimator.alignObjectSize(shallowInstanceSize),
-                      referenceFields.toArray(new Field[referenceFields.size()]));
-              return cachedInfo;
-            });
+
+                  cachedInfo =
+                      new ClassCache(
+                          RamUsageEstimator.alignObjectSize(shallowInstanceSize),
+                          referenceFields.toArray(new Field[referenceFields.size()]));
+                  return cachedInfo;
+                });
+    return classCache;
   }
 
   private static long byteArraySize(int len) {
diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestSecurityManager.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestSecurityManager.java
index 51b5312..6cef472 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestSecurityManager.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestSecurityManager.java
@@ -19,6 +19,7 @@ package org.apache.lucene.tests.util;
 import java.lang.StackWalker.StackFrame;
 import java.util.Locale;
 import java.util.function.Predicate;
+import org.apache.lucene.util.SuppressForbidden;
 
 /**
  * A {@link SecurityManager} that prevents tests calling {@link System#exit(int)}. Only the test
@@ -28,6 +29,8 @@ import java.util.function.Predicate;
  * <p>Use this with {@code
  * -Djava.security.manager=org.apache.lucene.tests.util.TestSecurityManager}.
  */
+@SuppressForbidden(reason = "security manager")
+@SuppressWarnings("removal")
 public final class TestSecurityManager extends SecurityManager {
 
   private static final String JUNIT4_TEST_RUNNER_PACKAGE = "com.carrotsearch.ant.tasks.junit4.";