The example is a <pre> block in the class javadoc. Javadoc does not compile such blocks, so when the API changed nothing failed, and Lucene's own tests already use the new 3-argument call.
setForkJoinPool is gone and reorder now takes the pool as a third argument. Select the still to open it at full size. Generated with AI, checked against the code.- You want BP doc-id reordering and copy the class javadoc's "Typical usage": build a
ForkJoinPool, callreorderer.setForkJoinPool(pool), thenreorderer.reorder(SlowCodecReaderWrapper.wrap(reader), targetDir). - You expect the two calls to compile and the reordering to run on your pool, as they did on 9.8.0 to 9.11.1.
- Instead javac reports 2 errors on 10.0.0 to 10.6.0 and main: there is no method
setForkJoinPool, andreorderneeds 3 arguments (CodecReader, Directory, Executor), not 2. On 9.12.x only thereordererror appears, because the setter still exists there, deprecated. - Why: in 2024 (#13289) the pool moved from the setter to the new third
Executorargument ofreorder; Lucene's tests were updated, this example was not. Delete the setter line and passpoolas the third argument, and both calls compile.
Developers adopting the opt-in BP reordering tool of lucene-misc who start from its class javadoc: the copied calls fail to compile every time, on every release since 9.12.0. Documentation only: nothing runs differently, and the method javadoc of reorder shows the right signature.
Mechanism, terms and numbers386 words
BPIndexReorderer (lucene-misc) renumbers documents with recursive graph bisection so that similar documents sit together, which shrinks postings and can speed up queries. Its class javadoc, after describing the algorithm, says "Typical usage would look like this:" (line 73) and gives a 14-line example. Two of its lines name API that no longer exists: reorderer.setForkJoinPool(pool); (removed in 10.0.0) and reorderer.reorder(SlowCodecReaderWrapper.wrap(reader), targetDir) (the 2-argument form, removed in 9.12.0). The only public reorder is now reorder(CodecReader reader, Directory tempDir, Executor executor). Copied into a project, the two calls give cannot find symbol: method setForkJoinPool(java.util.concurrent.ForkJoinPool) and method reorder ... required: CodecReader,Directory,Executor; found: CodecReader,Directory on 10.0.0 to 10.6.0 and main, and the reorder error alone on 9.12.x. #13289 (2024-09-12) made both API changes and updated TestBPIndexReorderer to reorder(codecReader, dir, pool), but left the example. Passing the example's own pool as the third argument and deleting the setter line makes both calls compile; Lucene's 8 TestBPIndexReorderer tests pass with that javadoc change. Nothing in Lucene behaves wrongly; only the example is stale.
| line | text | exists? |
|---|---|---|
| 76-77 | LeafReader reader;, Directory targetDir; | placeholders |
| 79 | Directory targetDir = FSDirectory.open(targetPath); | yes (a second targetDir declaration; targetPath undeclared; side nit) |
| 80 | BPIndexReorderer reorderer = new BPIndexReorderer(); | yes (line 110) |
| 81-82 | ForkJoinPool pool = new ForkJoinPool(..., p -> new ForkJoinWorkerThread(p) {}, null, false); | yes (JDK) |
| 83 | reorderer.setForkJoinPool(pool); | no (removed in 10.0.0) |
| 84 | reorderer.setFields(Collections.singleton("body")); | yes (line 141) |
| 85 | CodecReader reorderedReaderView = reorderer.reorder(SlowCodecReaderWrapper.wrap(reader), targetDir); | no (2-argument form removed in 9.12.0) |
| 86-89 | IndexWriter.addIndexes(reorderedReaderView), DirectoryReader.open(targetDir) | yes |
public CodecReader reorder(CodecReader reader, Directory tempDir, Executor executor) (line 838): "The provided Executor can be used to perform reordering concurrently. A value of null indicates that reordering should be performed in the current thread." and "The provided Executor must not reject tasks." A ForkJoinPool is an Executor, so the example's own pool fits the third argument unchanged. setForkJoinPool occurs nowhere under lucene/ except the javadoc line 83.
Javadoc does not compile <pre> code and no test reads the example. TestBPIndexReorderer calls reorder(codecReader, dir, pool) (lines 122, 184) and reorder(codecReader, dir, null) (line 307).
That the block as a whole "does not compile": reader is never initialised, targetPath is undeclared and targetDir is declared twice; those are placeholders. The claim is about the two API calls.
Exposure and likelihood106 words
- Who. Readers of the
BPIndexReordererclass javadoc who copy its example, its only class-level usage guide. No query, document or index file reaches it. - Default vs opt-in. Opt-in: an expert, offline tool the application calls itself. No configuration or input changes the outcome: the copied calls always fail.
- Scale. 1 error on 9.12.0 to 9.12.3, 2 errors on 10.0.0 to 10.6.0 and main.
- Effect. A compile error, not wrong behaviour. The 9.12.x deprecation note on
setForkJoinPoolpointed to the 3-argumentreorder; it went with the method in 10.0.0. - Priority. Low; the same kind of defect as the other stale javadoc examples of the same sweep.
One JUnit class with one test. It compiles the example's two calls, copied verbatim, with javax.tools against the jars on the test class path, inside a method that declares reader, targetDir and pool, so every error is an API error. Nothing in Lucene runs, and nothing is random.
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.lucene.misc.index;
import java.net.URI;
import java.util.List;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.ToolProvider;
import org.apache.lucene.tests.util.LuceneTestCase;
public class TestBPIndexReordererJavadocExample extends LuceneTestCase {
public void testClassJavadocExampleCalls() throws Exception {
// expected: the class javadoc example's two reorderer calls compile; actual: both APIs are gone
String source =
"""
import java.util.concurrent.ForkJoinPool;
import org.apache.lucene.index.*;
import org.apache.lucene.misc.index.BPIndexReorderer;
import org.apache.lucene.store.Directory;
class Example {
CodecReader run(LeafReader reader, Directory targetDir, ForkJoinPool pool)
throws Exception {
BPIndexReorderer reorderer = new BPIndexReorderer();
reorderer.setForkJoinPool(pool);
return reorderer.reorder(SlowCodecReaderWrapper.wrap(reader), targetDir);
}
}
""";
JavaFileObject file =
new SimpleJavaFileObject(URI.create("string:///Example.java"), JavaFileObject.Kind.SOURCE) {
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return source;
}
};
JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
List<String> options =
List.of(
"-classpath", System.getProperty("java.class.path"),
"-d", createTempDir().toString(),
"-proc:none");
boolean compiled = javac.getTask(null, null, diagnostics, options, null, List.of(file)).call();
assertTrue("javac errors: " + diagnostics.getDiagnostics(), compiled);
}
}
# $LUCENE: a built checkout (./gradlew jar); $REPRO: the directory holding org/apache/lucene/misc/index/Test...java
# $DEPS: junit 4.13.2, randomizedtesting-runner 2.9.2, hamcrest 3.0
V=11.0.0-SNAPSHOT
CP=$LUCENE/lucene/core/build/libs/lucene-core-$V.jar:$LUCENE/lucene/codecs/build/libs/lucene-codecs-$V.jar:$LUCENE/lucene/test-framework/build/libs/lucene-test-framework-$V.jar:$LUCENE/lucene/misc/build/libs/lucene-misc-$V.jar:$DEPS
javac -d out -cp "$CP" $REPRO/org/apache/lucene/misc/index/TestBPIndexReordererJavadocExample.java
java -ea -Dtests.seed=DEADBEEF -cp "out:$CP" org.junit.runner.JUnitCore org.apache.lucene.misc.index.TestBPIndexReordererJavadocExample
# assertions off, same result: java -da -Dtests.asserts=false ...
- Expected
- The example's two reorderer calls compile.
- Observed
- Two javac errors on main and 10.6.0, with assertions on and off: no method
setForkJoinPool(ForkJoinPool), andreorderrequires(CodecReader, Directory, Executor)but got 2 arguments.
More files, environment, full output314 words
The two calls in the test were checked mechanically against BPIndexReorderer.java:83 and :85 at 645d4fe14a20: they are verbatim. /Example.java:10 and :11 in the output are those two lines.
Inside a Lucene checkout with gradle (./gradlew :lucene:misc:test --tests org.apache.lucene.misc.index.TestBPIndexReordererJavadocExample), the test as written fails for a class-path reason ("package org.apache.lucene.index does not exist"): Lucene's gradle test task runs lucene-core from the module path, which java.class.path does not include. Adding System.getProperty("jdk.module.path") to javac's -classpath fixes that; it then reports exactly the two errors below under gradle too (checked; the fixed twin passes under gradle).
No separate regression test is suggested: this test copies the example's calls, so it would not notice a later edit of the javadoc, and Lucene has no harness that compiles javadoc examples. TestBPIndexReorderer already exercises the 3-argument call with a pool.
| lucene | main 645d4fe14a20 (11.0.0-SNAPSHOT); the 10.6.0 and 10.0.0 release jars give the same 2 errors, 9.12.0 the reorder error only, 9.11.1 passes |
|---|---|
| jdk | OpenJDK 25.0.3 (build 25.0.3+9-LTS) |
| os | Linux aarch64 (a compile-only check: on any JDK 15 or later, which the test's text block needs, the two API errors do not depend on the platform) |
# the command above, main 645d4fe14a20, seed DEADBEEF, -ea (-da identical); header lines (JUnit banner, vectorization warning, NOTE lines, Time: 1.86) left out, ... = remaining runner frames
There was 1 failure:
1) testClassJavadocExampleCalls(org.apache.lucene.misc.index.TestBPIndexReordererJavadocExample)
java.lang.AssertionError: javac errors: [/Example.java:10: error: cannot find symbol
reorderer.setForkJoinPool(pool);
^
symbol: method setForkJoinPool(java.util.concurrent.ForkJoinPool)
location: variable reorderer of type org.apache.lucene.misc.index.BPIndexReorderer, /Example.java:11: error: method reorder in class org.apache.lucene.misc.index.BPIndexReorderer cannot be applied to given types;
return reorderer.reorder(SlowCodecReaderWrapper.wrap(reader), targetDir);
^
required: org.apache.lucene.index.CodecReader,org.apache.lucene.store.Directory,java.util.concurrent.Executor
found: org.apache.lucene.index.CodecReader,org.apache.lucene.store.Directory
reason: actual and formal argument lists differ in length]
at __randomizedtesting.SeedInfo.seed([DEADBEEF:6C73A58A0D93465A]:0)
at org.junit.Assert.fail(Assert.java:89)
at org.junit.Assert.assertTrue(Assert.java:42)
at org.apache.lucene.misc.index.TestBPIndexReordererJavadocExample.testClassJavadocExampleCalls(TestBPIndexReordererJavadocExample.java:63)
...
FAILURES!!!
Tests run: 1, Failures: 1
# 10.6.0 and 10.0.0 release jars, -da: the same 2 errors; 9.12.0: only the reorder error (plus javac's deprecation note); 9.11.1: passes- The block is introduced as "Typical usage would look like this:", and its two calls compiled verbatim on 9.8.0 to 9.11.1.
- #13289 gave
reorderanExecutorargument and updated Lucene's tests toreorder(codecReader, dir, pool), but not this example; no CHANGES or MIGRATE entry mentions it. - Lucene has fixed stale javadoc examples before as ordinary doc fixes (LUCENE-9046, #12693).
The full argument178 words
- Offered as working code. "Typical usage would look like this:" (line 73), with no pseudo-code marker.
- Maintained as real code. #12568 (
36432fa6724, 2023-09-19) replacedsetForkJoinPool(ForkJoinPool.commonPool())with the custom-factory pool, and1d0edd76a5e("Fix compilation under Java 11.", the same day) escaped the lambda's->in it as->(the Java 11 problem of that day's dev@ thread) and replaced a test-onlyrandom().nextBoolean()withfalse. - The API change forgot it. #13289 (
ff8b81afc59, Adrien Grand, 2024-09-12) removedsetForkJoinPoolon main (deprecated it on branch_9x: "Pass an executor to reorder(CodecReader, Directory, Executor) instead") and gavereordertheExecutorargument. It updatedTestBPIndexReordererfromsetForkJoinPool(pool)+reorder(codecReader, dir)toreorder(codecReader, dir, pool); none of its hunks touches the class javadoc, and its discussion never mentions it. - Public API. The class is public, in an exported package, with no
@lucene.experimentalor@lucene.internaltag. - Precedent. LUCENE-9046 "Fix wrong example in Javadoc of TermInSetQuery"; #12693 "chore: update the Javadoc example in Analyzer" (2023-10-18); LUCENE-7763 removed an outdated javadoc comment (LUCENE-9046 and LUCENE-7763 were found by the cross-model reviewer, OpenAI GPT-5.6).
The devil's-advocate check120 words
Strongest case for "not a bug": the block is illustrative pseudo-code. It never compiled as written (reader uninitialised, targetPath undeclared, targetDir declared twice), Lucene does not compile javadoc snippets, lucene-misc changes freely, the error is loud and the method javadoc is right.
Why it fails: it explains the placeholders, not two exact method calls. A reader supplies reader and targetPath; no context makes a removed method compile. The calls were edited as real code, compiled verbatim until 9.11.1, and broke only because #13289 changed the API without touching the example. The verifiers and the adjudication called it real (the refute lens could not run anything; its "not real" is procedural); the adjudication rated it a Low documentation defect.
Recommended Pass the pool to reorder (validated)
Javadoc only: delete reorderer.setForkJoinPool(pool); and pass the pool as the third argument, reorder(SlowCodecReaderWrapper.wrap(reader), targetDir, pool), the same change #13289 made in Lucene's tests. Validated: the patched calls compile on main and 10.6.0, and TestBPIndexReorderer (8 tests) passes.
- * reorderer.setForkJoinPool(pool);
* reorderer.setFields(Collections.singleton("body"));
- * CodecReader reorderedReaderView = reorderer.reorder(SlowCodecReaderWrapper.wrap(reader), targetDir);
+ * CodecReader reorderedReaderView = reorderer.reorder(SlowCodecReaderWrapper.wrap(reader), targetDir, pool);All options and trade-offs3 options · 422 words
One fix was validated, with the javadoc diff applied to 645d4fe14a20; the optional extras were not run.
Javadoc only, lucene/misc/src/java/org/apache/lucene/misc/index/BPIndexReorderer.java:83 and :85. A narrow API-drift fix: it makes the two calls compile, while the block keeps its placeholders (reader, targetPath, the duplicate targetDir, no imports), so it is still not a self-contained compilation unit.
- * reorderer.setForkJoinPool(pool);
* reorderer.setFields(Collections.singleton("body"));
- * CodecReader reorderedReaderView = reorderer.reorder(SlowCodecReaderWrapper.wrap(reader), targetDir);
+ * CodecReader reorderedReaderView = reorderer.reorder(SlowCodecReaderWrapper.wrap(reader), targetDir, pool);Trade-offs
None for users: documentation only. It keeps the pool as written (the devil's-advocate verifier's point); its custom thread factory came from #12568 ("Fix issues with BP tests and the security manager."), and whether the example still needs it is a separate question. reorder needs an Executor that does not reject tasks (line 834), which a live ForkJoinPool satisfies; the example never shuts the pool down (the devil's-advocate verifier's run did), and a pool.shutdown() after use would be optional polish (not run).
What the checks validated
- The minimal test with its two calls taken mechanically from the patched javadoc passes 1 of 1: plain
javac/javaon main with assertions on and off, standalone on main (on and off) and on the 10.6.0 jars, and under./gradlew :lucene:misc:test(gradle form). The stock calls fail the same test, so it detects the bug. ./gradlew :lucene:misc:test --tests org.apache.lucene.misc.index.TestBPIndexReorderer -Ptests.seed=DEADBEEF: 8 tests, 0 failures../gradlew :lucene:misc:checkGoogleJavaFormatand:lucene:misc:renderJavadocpass; the rendered class page shows the 3-argument call and nosetForkJoinPool.- At runtime, the devil's-advocate verifier ran the corrected calls on a real 200-document index on an earlier main with the same file:
addIndexesandDirectoryReader.opensucceed and all 200 ids survive.
Replace line 77 Directory targetDir; // Directory where to write the reordered index with Path targetPath; // where to write the reordered index: this removes the duplicate targetDir declaration and declares targetPath in one line.
Trade-offs
The adjudication's fix sketch includes removing the duplicate Directory targetDir; line, as a side nit the claim does not rest on.
The parameter is tempDir; the example passes targetDir, which works but may surprise. reorder writes its temporary files through a TrackingDirectoryWrapper over that directory (line 850) and deletes them before it returns (line 896; line 900 on failure). A short trailing comment, or a separate temporary directory, would make the contract explicit.
Trade-offs
Documentation only; no behaviour change.
No formal method. A sweep compiled every Java code block in the non-sandbox javadocs against the main jars and flagged this block with cannot find symbol: method setForkJoinPool; a targeted test then found the reorder error too. Independent verifiers reproduced it with their own tests.
The method in full69 words
- Sweep. A hunt unit for javadoc examples (siblings of another contributor's fix #16904) compiled every
<pre><code class="language-java">block of the non-sandboxlucene/**/src/javafiles withjavax.toolsagainst the stock main jars and flagged this block (2026-10-28). - Targeted test. A public-API JUnit compiled the block verbatim, declaring only the undeclared name
targetPathand counting only API-level errors; it found both errors and the version split. - Tier. Non-formal: it compiles documentation code.
No prior report found: GitHub issues and PRs, commits, the dev@, java-user@ and issues@ lists, downstream repositories and the web were searched on 2026-10-29; re-checked 2026-11-01. setForkJoinPool matches no Lucene issue or PR; no open or recent PR changes the example.
Searches3 searches
Related, not reports: #13289 made the example stale (its discussion never mentions it); #12489 and #12568 wrote it (its calls valid then); the dev@ thread of 2023-09-19 on #12568 (Uwe Schindler and Adrien Grand) is about a different, fixed Java 11 compile problem in this block; castorini/anserini#2289 is a 2023 usage snippet, valid then. The JIRA archive cannot hold a report: the class postdates the migration.
Others are filing stale-javadoc fixes in other files (#16904 and a series of issues).
| Where | When | How | Found |
|---|---|---|---|
| Scripted searches, 2 runs | 2026-10-29 | 51 queries each (class and method names, error text, javadoc/example phrasings) over GitHub issues, PRs and commits, downstream repositories, dev@, java-user@, issues@ and the JIRA archive, plus the web | 0 high hits |
| GitHub and lists, manual | 2026-10-29 | 40 search phrasings; the changed files of all 414 open PRs; the full conversation and reviews of #13289; lists.apache.org | 3 open PRs touch the file, none the example block; only the 2023 dev@ thread on a different defect |
| Re-check | 2026-11-01 | issue and PR search for BPIndexReorderer, setForkJoinPool, "BPIndexReorderer javadoc"; the changed files of all 52 PRs updated since 2026-10-29; the file on main, branch_11x and branch_10_6 | the same 7 unrelated items, 0, 0; no PR changes the file; both stale lines still on every branch |
The example was written in 2023 (#12489, #12568) and was right until #13289 (2024-09-12) changed the API: the 9.x backport removed the 2-argument reorder in 9.12.0 and deprecated setForkJoinPool, which 10.0.0 removed.
Versions tested6 rows
- Written:
39f3777886c(#12489, 2023-09-14, the class and thereorderline; first released in 9.8.0) and36432fa6724(#12568, 2023-09-19, the pool and setter lines). - Made stale:
ff8b81afc59on main (released in 10.0.0) and the backporta2290ecb237on branch_9x (released in 9.12.0), both #13289 by Adrien Grand, author date 2024-09-12. On branch_9xsetForkJoinPoolstayed as@Deprecated, so 9.12.x fails onreorderonly. - Since then: only markup changes (
378ca8d1bbf, #15573, 2026-01-15); the example text is identical at every release tag from 9.8.0 to 10.6.0 and on main.
| Version or commit | Verdict | Result |
|---|---|---|
main 645d4fe14a20; upstream main f815e679bf6c | affected | fails with 2 errors, -ea and -da (upstream main read, not run: the file is byte-identical) |
| 10.6.0 | affected | fails with 2 errors (release jars, -da; -ea too in the fact check) |
| 10.0.0 to 10.5.2 | affected | fails with 2 errors (10.0.0 and 10.5.2 run) |
| 9.12.0 to 9.12.3 | 1 error | fails on reorder only; setForkJoinPool still exists, deprecated (9.12.0 and 9.12.3 run) |
| 9.8.0 to 9.11.1 | not affected | both calls compile (9.8.0 and 9.11.1 run) |
| before 9.8.0 | no such class | not affected: BPIndexReorderer does not exist there |
A finder, an independent reproducer, a reviewer from another model family (OpenAI GPT-5.6) with lenses (reading only), a devil's-advocate check, an adjudication and an audit. Every check that ran code reproduced it; the adjudication confirmed it with high confidence as a Low documentation defect.
Checks and verdicts165 words
The cross-model reviews could not run code.
| Check | Verdict | What it found |
|---|---|---|
| Finder | reproduced (doc) | Compile sweep, then a JUnit compiling the whole block: fails on main (-ea, -da), 10.5.2, and 9.12.3 (reorder only). |
| Refute lens (OpenAI GPT-5.6) | not a valid review | Reading only; its "not real" is procedural, as its own notes say. |
| Reproducer | real | Own test with a corrected control: fails on main, 10.5.2, 10.0.0, 9.12.3, 9.12.0; 9.11.1 is the inverse control. |
| Intended lens (OpenAI GPT-5.6) | real, medium | The pseudo-code argument is weak; found the LUCENE-9046 and LUCENE-7763 precedents. |
| Devil's advocate | real, high | Three controls pass; ran the corrected calls on a real 200-document index. |
| Adjudication and audit | confirmed (high), minor | Re-ran with new seeds on main (-ea, -da); 9.11.1 inverse control. |
| Brief | verified; fix validated | Minimal test fails on main (-ea, -da), 10.6.0, 10.0.0 and 9.12.0 (1 error), passes on 9.11.1; the patched calls pass; the module's TestBPIndexReorderer passes. |
The diagram as a still image, generated with AI and checked against the code. It is under 10 MB, the limit for a GitHub attachment.
- PNG 394 KB
Finding record, Lucene and upstream sources, repro files and diagram notes1,344 words
- Registry title
- BPIndexReorderer's class javadoc 'Typical usage' example calls reorderer.setForkJoinPool(pool), removed in 10.0.0, and the 2-argument reorder(reader, targetDir), removed in 9.12.0, so it names APIs that no longer exist; #13289 moved the class to an Executor argument, reorder(CodecReader, Directory, Executor), and left the example unchanged (documentation defect)
- Area
- misc / index reordering (BPIndexReorderer class javadoc example)
- Priority
- Low, rank 1254: The BPIndexReorderer 'Typical usage' example in lucene-misc calls removed APIs and fails loudly at compile time while the method javadoc is right, a niche-module doc defect.
- Impact class
- minor
- Impact note
- Documentation only, with no runtime effect: a developer who adopts the opt-in BP doc-id reordering tool of lucene-misc by copying its class javadoc example gets compile errors on every release since 9.12.0 (1 on 9.12.x, where only the reorder call fails; 2 on 10.0.0 through 10.6.0 and main) and has to find the Executor-based signature in the method javadoc; nothing wrong ever runs, and no scale or special input is involved.
- Summary
- The BPIndexReorderer javadoc shows 'typical usage': build a ForkJoinPool, hand it to reorderer.setForkJoinPool(pool), then call reorderer.reorder(reader, targetDir). If you copy that into your code it does not compile on any release since 9.12.0: setForkJoinPool no longer exists (removed in 10.0.0) and reorder now needs a third argument, the Executor to run on. Passing the same pool as that third argument (and deleting the setter line) compiles and works, so only the code shown in the javadoc is wrong.
- Introduced
- ff8b81afc59 (#13289 'Integrate merge-time index reordering with the intra-merge executor.', by jpountz, author date = merge date 2024-09-12; branch_9x backport a2290ecb237, same author date): it replaced reorder(CodecReader, Directory) by reorder(CodecReader, Directory, Executor) and removed setForkJoinPool on main (on branch_9x it kept setForkJoinPool as @Deprecated, 'Pass an executor to reorder(CodecReader, Directory, Executor) instead'), updated TestBPIndexReorderer, and left the class javadoc example as it was (none of its hunks touches the example; no CHANGES or MIGRATE entry). The example itself dates from 39f3777886c (#12489, 2023-09-14, the reorder line) and 36432fa6724 (#12568, 2023-09-19, the setForkJoinPool(pool) line), both valid when written [read: git log, git blame and git show in the full-history clone; exec: release sweep, see affected_versions] (2024-09-12 (ff8b81afc59, #13289, author and merge date; the branch_9x backport a2290ecb237 has the same author date))
- First affected version
- 9.12.0 [exec] (only the 2-argument reorder fails there; setForkJoinPool still exists, deprecated); 10.0.0 [exec] is the first release where both calls fail
- Affected versions
- 9.12.0-9.12.3 (1 broken call: reorder), every 10.x release from 10.0.0 to 10.5.2 (2 broken calls: setForkJoinPool and reorder), 10.6.0 (released 2026-10-29; branch_10_6 4ae946e5a9b) [exec 2026-11-01: the minimal test fails on the 10.6.0 release jars with assertions on and off, 2 errors] and main a9779ef3c193; not affected: 9.8.0-9.11.1 (the verbatim example compiles; the class did not exist before 9.8.0). Not fixed upstream: main 645d4fe14a20, branch_11x, branch_10_6 and branch_10x still carry both stale lines (2026-10-29). [exec: the finder's JUnit fails on main (-ea and -da), 10.5.2, 10.0.0, 9.12.3 and 9.12.0 and passes on 9.11.1 and 9.8.0 (the follow-up's release sweep); the independent reproduction's JUnit, with a corrected-example control, fails on main (-ea and -da), 10.5.2 (-ea and -da), 10.0.0, 9.12.3 and 9.12.0, while on 9.11.1 the verbatim example compiles and the corrected one does not] [read: the example text is identical at every tag from 9.8.0 to 10.5.2 and on main (extracted, entity-decoded and diffed per tag), and the API presence was tabulated per tag: setForkJoinPool 9.8.0-9.12.3, reorder(CodecReader, Directory) 9.8.0-9.11.1]. Caveat: all runs used JDK 25 on Linux aarch64.
- Status
- documented (brief, checks and a per-finding doc exist)
- Verification
- Confirmed by AI-run checks: an independent repro, a cross-model review that could only read the code (its low-confidence “not real” is procedural), an intended-behaviour check, a prior-report search and a skeptical audit; not yet triaged by a person.
- Found by
- non-formal
- Upstream and prior reports
- none found (searched 2026-10-29 and rechecked the same day): two scripted search runs (51 queries each over GitHub issues, PRs and commits, downstream repositories, the dev@, java-user@ and issues@ lists, the JIRA archive and the web; 0 high hits), 40 GitHub search phrasings (class and method names, 'reorderedReaderView', 'Typical usage would look like this', javadoc/example/stale/'does not compile' variants, the recent javadoc-fix authors), the changed files of all 414 open apache/lucene PRs (three, #15430, #13186 and #16847, touch BPIndexReorderer.java, none of them lines 73-91), the 93 issues and PRs created since 2026-10-25, the full conversation and reviews of #13289 (the example is never mentioned), lists.apache.org and 6 web searches. The JIRA archive cannot hold a report (the class was added in 2023-09, after the JIRA migration). Read but not the same bug: #13289 (the change that made the example stale), #12489 and #12568 (they wrote the example, valid then), the dev@ thread of 2023-09-19 on #12568 (Uwe Schindler and Adrien Grand on a different, fixed Java 11 compile problem in this block), castorini/anserini#2289 (a 2023 usage snippet, valid then), #16729, #12721, #13565, #12665, #12622, #12645, #14097, and the parallel outside javadoc series (hidingmyname #16821-#16828, #16920-#16922, #16927-#16936; Deepcodr #16904), none of which covers lucene/misc. Recheck: the 35 issues and PRs updated since 2026-10-28 name neither the class nor the API, and none of their 27 PRs changes BPIndexReorderer.java (#16919 and #16571 touch other misc/index files); search 'setForkJoinPool' and 'BPIndexReorderer javadoc' return 0; the file's latest upstream commit by author date is 54283150a81 (#16255, 2026-06-14); main 645d4fe14a20, branch_11x, branch_10_6 and branch_10x still carry both stale lines. Tracking issue #16937 does not name it.
- Lucene commit tested
- main
645d4fe14a20(2026-10-28): the minimal test fails with assertions on and off (standalone, with a plainjavac/javacommand); the 10.6.0 and 10.0.0 release jars give the same 2 errors, 9.12.0 thereordererror only, and on 9.11.1 the test passes. The fix was checked with the javadoc diff applied to645d4fe14a20: the patched calls compile on main and on 10.6.0;./gradlew :lucene:misc:test --tests TestBPIndexReorderer(8 tests),:lucene:misc:checkGoogleJavaFormatand:lucene:misc:renderJavadocpass. Upstream mainf815e679bf6c(2026-11-01) was read, not run: the file is byte-identical.
- Finding record
lucene/misc/src/java/org/apache/lucene/misc/index/BPIndexReorderer.java:73-91 (class javadoc 'Typical usage would look like this:' and the example; :77 and :79 the duplicate targetDir, :83 setForkJoinPool(pool), :85 the 2-argument reorder) and :838 (the only public reorder: reorder(CodecReader reader, Directory tempDir, Executor executor)); setForkJoinPool occurs nowhere else under lucene/
- The finding in 30 seconds
a Lucene main checkout (645d4fe14a20) lucene/misc/src/java/org/apache/lucene/misc/index/BPIndexReorderer.java:73-90 (the example; :83 setForkJoinPool, :85 2-argument reorder; :77 and :79 targetDir), :110 (constructor), :141 (setFields), :825-838 (reorder(CodecReader, Directory, Executor) and its javadoc), :779 (computeDocMap)a Lucene main checkout (645d4fe14a20) lucene/misc/src/test/org/apache/lucene/misc/index/TestBPIndexReorderer.java:57-58 (thread factory comment), :122, :184 (reorder(codecReader, dir, pool)), :307 (reorder(codecReader, dir, null))a Lucene main checkout (645d4fe14a20): grep for setForkJoinPool over lucene/ (only BPIndexReorderer.java:83)
- Why it looks unintended
a Lucene main checkout (645d4fe14a20) lucene/misc/src/java/org/apache/lucene/misc/index/BPIndexReorderer.java:73a Lucene main checkout (645d4fe14a20) lucene/misc/src/java/module-info.java:24 (exports org.apache.lucene.misc.index); lucene/CHANGES.txt:6147 (LUCENE-9046), :8358 (LUCENE-7763); grep of CHANGES.txt and MIGRATE.md for 13289, BPIndexReorderer, setForkJoinPool (no hit)
- Suggested fix
a Lucene main checkout (645d4fe14a20) lucene/misc/src/java/org/apache/lucene/misc/index/BPIndexReorderer.java:834 (the Executor must not reject tasks), :850, :896, :900 (temporary files tracked and deleted)a Lucene main checkout (645d4fe14a20) lucene/misc/src/test/org/apache/lucene/misc/index/TestBPIndexReorderer.java:122, :184 (#13289's own update)
- TestBPIndexReordererJavadocExample.java (one test, public API):
repro/LFV-984/src/org/apache/lucene/misc/index/TestBPIndexReordererJavadocExample.java(65 lines)
Made in parallel with this doc from the mechanism in the brief; the PNG is the summary frame. Its numbers come from its own probe on main: javac on the copied calls, and the fixed example run on a 10,000-document test index whose body alternates between even and odd by id. "16 runs instead of 10,000" counts maximal runs of consecutive documents of the same parity after reordering (10,000 before). In its release row, 9.7.0 ("no such class") and 10.6.0 ("2, by reading") were read at their tags, not compiled by that probe; this doc's runs compiled the test against the 10.6.0 jars (2 errors).
assets/LFV-984/bug.png(394 KB)
