Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrap Query rewrite backwards layer with AccessController #12308

Merged
merged 4 commits into from
May 19, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
8 changes: 6 additions & 2 deletions lucene/CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,12 @@ http://s.apache.org/luceneversions
API Changes
---------------------

* GITHUB#11840: Query rewrite now takes an IndexSearcher instead of IndexReader to enable concurrent
rewriting. (Patrick Zhai, Ben Trent)
* GITHUB#11840, GITHUB#12304: Query rewrite now takes an IndexSearcher instead of
IndexReader to enable concurrent rewriting. Please note: This is implemented in
a backwards compatible way. A query overriding any of both rewrite methods is
supported. To implement this backwards layer in Lucene 9.x the
RuntimePermission "accessDeclaredMembers" is needed in applications using
SecurityManager. (Patrick Zhai, Ben Trent, Uwe Schindler)

New Features
---------------------
Expand Down
8 changes: 7 additions & 1 deletion lucene/core/src/java/org/apache/lucene/search/Query.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
package org.apache.lucene.search;

import java.io.IOException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.util.VirtualMethod;

Expand Down Expand Up @@ -51,7 +53,11 @@ public abstract class Query {
private static final VirtualMethod<Query> newMethod =
new VirtualMethod<>(Query.class, "rewrite", IndexSearcher.class);
private final boolean isDeprecatedRewriteMethodOverridden =
VirtualMethod.compareImplementationDistance(this.getClass(), oldMethod, newMethod) > 0;
AccessController.doPrivileged(
(PrivilegedAction<Boolean>)
() ->
VirtualMethod.compareImplementationDistance(this.getClass(), oldMethod, newMethod)
> 0);

/**
* Prints a query to a string, with <code>field</code> assumed to be the default field and
Expand Down
13 changes: 11 additions & 2 deletions lucene/core/src/java/org/apache/lucene/util/VirtualMethod.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
package org.apache.lucene.util;

import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
Expand Down Expand Up @@ -49,13 +51,20 @@
*
* <pre class="prettyprint">
* final boolean isDeprecatedMethodOverridden =
* oldMethod.getImplementationDistance(this.getClass()) &gt; newMethod.getImplementationDistance(this.getClass());
* AccessController.doPrivileged((PrivilegedAction&lt;Boolean&gt;) () -&gt;
* (oldMethod.getImplementationDistance(this.getClass()) &gt; newMethod.getImplementationDistance(this.getClass())));
*
* <em>// alternatively (more readable):</em>
* final boolean isDeprecatedMethodOverridden =
* VirtualMethod.compareImplementationDistance(this.getClass(), oldMethod, newMethod) &gt; 0
* AccessController.doPrivileged((PrivilegedAction&lt;Boolean&gt;) () -&gt;
* VirtualMethod.compareImplementationDistance(this.getClass(), oldMethod, newMethod) &gt; 0);
* </pre>
*
* <p>It is important to use {@link AccessController#doPrivileged(PrivilegedAction)} for the actual
* call to get the implementation distance because the subclass may be in a different package. The
* static constructors do not need to use {@code AccessController} because it just initializes our
* own method reference. The caller should have access to all declared members in its own class.
*
* <p>{@link #getImplementationDistance} returns the distance of the subclass that overrides this
* method. The one with the larger distance should be used preferable. This way also more
* complicated method rename scenarios can be handled (think of 2.9 {@code TokenStream}
Expand Down