Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions lucene/CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,9 @@ Bug Fixes
* GITHUB#12419, GITHUB#15119, GITHUB#15864: Fix circular dependency deadlock in
TestSecrets initialization (Namgyu Kim, Uwe Schindler)

* GITHUB#15867: Use IllegalCallerException to signal wrong caller in internal classes
(VectorizationProvider, TestSecrets). (Uwe Schindler)

Other
---------------------
* GITHUB#15586: Document that scoring and ranking may change across major Lucene versions, and that applications requiring stable ranking should explicitly configure Similarity. (Parveen Saini)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,58 +106,46 @@ public static FilterIndexInputAccess getFilterInputIndexAccess() {

/** For internal initialization only. */
public static void setIndexWriterAccess(IndexWriterAccess indexWriterAccess) {
ensureCallerForSetter(IndexWriter.class);
ensureNull(TestSecrets.indexWriterAccess);
ensureCallerForSetter(IndexWriter.class, TestSecrets.indexWriterAccess);
TestSecrets.indexWriterAccess = indexWriterAccess;
}

/** For internal initialization only. */
public static void setIndexPackageAccess(IndexPackageAccess indexPackageAccess) {
ensureCallerForSetter(IndexWriter.class);
ensureNull(TestSecrets.indexPackageAccess);
ensureCallerForSetter(IndexWriter.class, TestSecrets.indexPackageAccess);
TestSecrets.indexPackageAccess = indexPackageAccess;
}

/** For internal initialization only. */
public static void setConcurrentMergeSchedulerAccess(ConcurrentMergeSchedulerAccess cmsAccess) {
ensureCallerForSetter(ConcurrentMergeScheduler.class);
ensureNull(TestSecrets.cmsAccess);
ensureCallerForSetter(ConcurrentMergeScheduler.class, TestSecrets.cmsAccess);
TestSecrets.cmsAccess = cmsAccess;
}

/** For internal initialization only. */
public static void setSegmentReaderAccess(SegmentReaderAccess segmentReaderAccess) {
ensureCallerForSetter(SegmentReader.class);
ensureNull(TestSecrets.segmentReaderAccess);
ensureCallerForSetter(SegmentReader.class, TestSecrets.segmentReaderAccess);
TestSecrets.segmentReaderAccess = segmentReaderAccess;
}

/** For internal initialization only. */
public static void setFilterInputIndexAccess(FilterIndexInputAccess filterIndexInputAccess) {
ensureCallerForSetter(FilterIndexInput.class);
ensureNull(TestSecrets.filterIndexInputAccess);
ensureCallerForSetter(FilterIndexInput.class, TestSecrets.filterIndexInputAccess);
TestSecrets.filterIndexInputAccess = filterIndexInputAccess;
}

private static void ensureNull(Object ob) {
if (ob != null) {
throw new UnsupportedOperationException(
"The accessor is already set. It can only be called from inside Lucene Core.");
}
}

private static void ensureCallerForSetter(Class<?> allowedCaller) {
private static void ensureCallerForSetter(Class<?> allowedCaller, Object needsNull) {
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() + ".");
.allMatch(allowedCaller.getName()::equals));
if (!validCaller || needsNull != null) {
throw new IllegalCallerException(
"The accessor can only be set once by " + allowedCaller.getName() + ".");
}
}

Expand All @@ -175,7 +163,7 @@ private static void ensureCallerForGetter() {
|| c.equals(
"org.apache.lucene.index.TestClassloadingDeadlock")));
if (!validCaller) {
throw new UnsupportedOperationException(
throw new IllegalCallerException(
"Lucene TestSecrets can only be used by the test-framework.");
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,7 @@ private static int getUpperJavaFeatureVersion() {
* Returns the default instance of the provider matching vectorization possibilities of actual
* runtime.
*
* @throws UnsupportedOperationException if the singleton getter is not called from known Lucene
* classes.
* @throws IllegalCallerException if the singleton getter is not called from known Lucene classes.
*/
public static VectorizationProvider getInstance() {
ensureCaller();
Expand Down Expand Up @@ -225,7 +224,7 @@ private static void ensureCaller() {
.map(StackFrame::getClassName)
.allMatch(VALID_CALLERS::contains));
if (!validCaller) {
throw new UnsupportedOperationException(
throw new IllegalCallerException(
"VectorizationProvider is internal and can only be used by known Lucene classes.");
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
public class TestTestSecrets extends LuceneTestCase {

public void testCallerOfGetter() {
final UnsupportedOperationException expected =
expectThrows(UnsupportedOperationException.class, TestTestSecrets::illegalCaller);
final IllegalCallerException expected =
expectThrows(IllegalCallerException.class, TestTestSecrets::illegalCaller);
assertEquals(
"Lucene TestSecrets can only be used by the test-framework.", expected.getMessage());
}
Expand All @@ -32,13 +32,10 @@ private static void illegalCaller() {
}

public void testCannotSet() {
expectThrows(UnsupportedOperationException.class, () -> TestSecrets.setIndexWriterAccess(null));
expectThrows(IllegalCallerException.class, () -> TestSecrets.setIndexWriterAccess(null));
expectThrows(
UnsupportedOperationException.class,
() -> TestSecrets.setConcurrentMergeSchedulerAccess(null));
expectThrows(
UnsupportedOperationException.class, () -> TestSecrets.setIndexPackageAccess(null));
expectThrows(
UnsupportedOperationException.class, () -> TestSecrets.setSegmentReaderAccess(null));
IllegalCallerException.class, () -> TestSecrets.setConcurrentMergeSchedulerAccess(null));
expectThrows(IllegalCallerException.class, () -> TestSecrets.setIndexPackageAccess(null));
expectThrows(IllegalCallerException.class, () -> TestSecrets.setSegmentReaderAccess(null));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
public class TestVectorizationProvider extends LuceneTestCase {

public void testCallerOfGetter() {
expectThrows(UnsupportedOperationException.class, TestVectorizationProvider::illegalCaller);
expectThrows(IllegalCallerException.class, TestVectorizationProvider::illegalCaller);
}

private static void illegalCaller() {
Expand Down
Loading