A javadoc example that shows how to build a geo distance query calls a method signature that does not exist.
LatLonShapeindexes points, lines and polygons given in latitude and longitude. Its query factories take the field, a query geometry such as aCircle(a centre and a radius in metres), and aShapeField.QueryRelation.- The relation says which indexed shapes match:
INTERSECTS(the shape touches or overlaps the geometry),WITHIN,DISJOINTorCONTAINS. For indexed points,INTERSECTSwith a circle means "within the radius".
circle as the QueryRelation (the Circle... part may be empty, so two arguments fit); and the fix, which compiles and matches only the near one of two points 500 m and 5 km from the centre. Select the still to open it at full size. Generated with AI, checked against the code.- You want a geo distance query, so you copy the example from the
Circleclass javadoc: a circle of 1 km around the Eiffel Tower,new Circle(48.8584, 2.2945, 1000), thenQuery query = LatLonShape.newDistanceQuery("location", circle);. - You expect it to compile and, on an index with two points 500 m and 5 km north of the centre, to match 1 document: the near one.
- Instead javac stops with 1 error, on 10.3.0, 10.6.0 and main: "incompatible types: Circle cannot be converted to QueryRelation".
- Why: the only overload is
newDistanceQuery(String field, QueryRelation queryRelation, Circle... circle), unchanged since 8.5.0. The circles are varargs, so javac readscircleas the missing relation. No two-argument form has ever existed, so the example never compiled. - Fix: write
LatLonShape.newDistanceQuery("location", ShapeField.QueryRelation.INTERSECTS, circle). It compiles and matches exactly the point 500 m away.
Developers who start with Lucene's geo shape queries from the Circle javadoc (an @lucene.experimental class) and copy its only example, on any release from 10.3.0 to 10.6.0 or main. Nothing wrong ever runs: javac refuses the line and names the missing QueryRelation. Low impact, but plainly wrong.
Mechanism, terms and numbers438 words
The class javadoc of org.apache.lucene.geo.Circle has one "Example usage" (Circle.java:37-45 on main 645d4fe14a20): a circle of 1 km around the Eiffel Tower, then Query query = LatLonShape.newDistanceQuery("location", circle); (:44). Copied into code, that line does not compile on any release that has the example (10.3.0 to 10.6.0) or on main. The only LatLonShape.newDistanceQuery is newDistanceQuery(String field, QueryRelation queryRelation, Circle... circle) (LatLonShape.java:316-319), which has needed a ShapeField.QueryRelation since LUCENE-8707 added it in 8.5.0; no two-argument form has ever existed, so the example, added by #14534 in 10.3.0, could not compile on the day it was written. With ShapeField.QueryRelation.INTERSECTS the call compiles and, of two points 500 m and 5 km from the centre, matches only the near one. No runtime code is wrong.
// Create a circle with 1km radius around the Eiffel Tower
Circle circle = new Circle(48.8584, 2.2945, 1000);
// Create a query using this circle
Query query = LatLonShape.newDistanceQuery("location", circle);LatLonShape.java:315-319: the only overload ispublic static Query newDistanceQuery(String field, QueryRelation queryRelation, Circle... circle), documented as "create a query to find all polygons that intersect a provided circle."- Because the circles are varargs, a two-argument call has a matching arity (field, relation, zero circles), so javac tries to pass
circleas theQueryRelationand reportsincompatible types: Circle cannot be converted to QueryRelationat the query line (the test, which calls the compiler throughjavax.tools, prints the type names in full). A single non-varargs method with the same three parameters would get an arity error instead ("actual and formal argument lists differ in length");-Xdiags:verboseconfirms the mechanism: "required: String,QueryRelation,Circle[] found: String,Circle reason: argument mismatch". - No
(String, Circle)method exists anywhere:LatLonPoint.newDistanceQuerytakes(String, double, double, double)(LatLonPoint.java:296-297),LatLonPoint.newGeometryQuerytakes(String, ShapeField.QueryRelation, LatLonGeometry...)(:327-328), andXYShape.newDistanceQuerytakes(String, QueryRelation, XYCircle...)(XYShape.java:252-253). A class-file scan of 159 core jars, 1.9.1 to main, finds no(String, Circle)overload in any build. ShapeField.QueryRelation(ShapeField.java:119-128) has the valuesINTERSECTS,WITHIN,DISJOINTandCONTAINS;INTERSECTSmatches the method's own javadoc.
Nothing in the build compiles <pre>{@code} blocks. The build enables Error Prone's InvalidSnippet check, which covers @snippet tags only (an observation of the hunt's devil's-advocate verifier). The open issue #9534 (LUCENE-8488) asks for compile-checked javadoc examples in general.
The other code examples the same change added (Rectangle.java:53-60, geo/package-info.java:64-65) compile and run once Rectangle's free names lat, lon and radiusMeters are declared, so this is the one broken example in it.
Exposure and likelihood156 words
- Who is hit. Anyone who copies the only code example in the
Circleclass javadoc to build a distance query on aLatLonShapefield.Circleis@lucene.experimental(Circle.java:47). - Default vs opt-in. Not a configuration matter: every copy fails, on every release that has the example (10.3.0 to 10.6.0) and on main.
- Scale. One line, one compile error. The message names
ShapeField.QueryRelation, so a developer can recover from the method signature, but must then choose a relation the example does not explain: for indexed pointsINTERSECTSmeans "within 1 km", for lines and polygons "touches or overlaps the circle" (a point the hunt's refute reviewer made). - What it does not do. No wrong results, no runtime path, no index change.
LatLonShape's API is right; only theCircleexample is wrong. (The method's one-line javadoc, "find all polygons that intersect a provided circle", describes only theINTERSECTScase; the method takes anyQueryRelation.)
One JUnit test compiles the example's two lines, copied verbatim, with the JDK's compiler against the Lucene jars on the class path. It adds only imports (ShapeField.QueryRelation included, so the type is in scope) and a small wrapper class. Deterministic, single thread, about 1.6 s; the same with assertions on and off.
/*
* 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.geo;
import java.net.URI;
import java.util.List;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.ToolProvider;
import org.apache.lucene.tests.util.LuceneTestCase;
public class TestCircleJavadocExample extends LuceneTestCase {
// Expected: the Circle class-javadoc example compiles; actual: javac says Circle cannot be converted to QueryRelation.
public void testClassJavadocExampleCompiles() throws Exception {
String source =
"""
import org.apache.lucene.document.LatLonShape;
import org.apache.lucene.document.ShapeField.QueryRelation;
import org.apache.lucene.geo.Circle;
import org.apache.lucene.search.Query;
class Example {
void example() {
Circle circle = new Circle(48.8584, 2.2945, 1000);
Query query = LatLonShape.newDistanceQuery("location", circle);
}
}
""";
JavaFileObject unit =
new SimpleJavaFileObject(URI.create("string:///Example.java"), JavaFileObject.Kind.SOURCE) {
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return source;
}
};
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
List<String> options =
List.of(
"-classpath", System.getProperty("java.class.path"),
"-d", createTempDir().toString(),
"-proc:none");
boolean compiled =
ToolProvider.getSystemJavaCompiler()
.getTask(null, null, diagnostics, options, null, List.of(unit))
.call();
assertTrue(diagnostics.getDiagnostics().toString(), compiled);
}
}
cp TestCircleJavadocExample.java $LUCENE/lucene/core/src/test/org/apache/lucene/geo/
cd $LUCENE && ./gradlew :lucene:core:test --tests org.apache.lucene.geo.TestCircleJavadocExample -Ptests.seed=DEADBEEF
# assertions off: add -Ptests.asserts=false (same result)
- Expected
- The example compiles, and the query matches 1 of 2 points (500 m in, 5 km out), as the corrected call does on main.
- Observed
- The compiler, called by the test through
javax.tools, reports 1 error at the query line:incompatible types: org.apache.lucene.geo.Circle cannot be converted to org.apache.lucene.document.ShapeField.QueryRelation; the same with assertions off. (Command-line javac prints the same error with short names:incompatible types: Circle cannot be converted to QueryRelation.)
More files, environment, full output243 words
- The test compiles the two statements of
Circle.java:41and:44verbatim withjavax.tools, againstjava.class.path.Example.java:8in the output is the example's query line,Circle.java:44. - Even simpler for a reader: paste the two lines into any method, import
LatLonShape,CircleandQuery, and compile; javac prints the same error with short type names:incompatible types: Circle cannot be converted to QueryRelation. - Results: fails 1 of 1 on main with assertions on and off, standalone (1.62 s) and through gradle, and on the published 10.6.0 and 10.3.0 jars. The hunt's and the verifiers' tests (the same call in larger tests) also fail on 10.5.2, the 10.6.0 RC1 and branch_10x
657014b3c579. - As a regression test: none is needed for a javadoc-only fix, and this test would not guard the javadoc anyway, because it compiles a copy of the text. The general guard is the tooling #9534 asks for.
| lucene | main 645d4fe14a20 (11.0.0-SNAPSHOT); the same test also fails on the published 10.6.0 and 10.3.0 jars |
|---|---|
| jdk | OpenJDK 25.0.3 (build 25.0.3+9-LTS) |
| os | Linux, aarch64 |
cp TestCircleJavadocExample.java $LUCENE/lucene/core/src/test/org/apache/lucene/geo/
cd $LUCENE && ./gradlew :lucene:core:test --tests org.apache.lucene.geo.TestCircleJavadocExample -Ptests.seed=DEADBEEF
# assertions off: add -Ptests.asserts=false (same result)
TestCircleJavadocExample > testClassJavadocExampleCompiles FAILED
java.lang.AssertionError: [/Example.java:8: error: incompatible types: org.apache.lucene.geo.Circle cannot be converted to org.apache.lucene.document.ShapeField.QueryRelation
Query query = LatLonShape.newDistanceQuery("location", circle);
^, Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output]
at __randomizedtesting.SeedInfo.seed([DEADBEEF:9A7EBD6A0F12FB11]:0)
at org.junit.Assert.fail(Assert.java:89)
at org.junit.Assert.assertTrue(Assert.java:42)
at org.apache.lucene.geo.TestCircleJavadocExample.testClassJavadocExampleCompiles(TestCircleJavadocExample.java:61)- It calls a two-argument
newDistanceQuerythat has never existed: since 8.5.0 the only form is(String, QueryRelation, Circle...). - It is headed "Example usage" with no omission marker, in a change meant to improve user-facing geo docs.
- The other examples from that change compile, and upstream has fixed wrong javadoc examples before.
The full argument163 words
- Contract text.
Circle.java:37: "Example usage:".LatLonShape.java:316-317:newDistanceQuery(String field, QueryRelation queryRelation, Circle... circle).LatLonShape's class javadoc describes each query factory it lists (box, line, polygon and geometry queries) as matching shapes "that have some {@link QueryRelation}" with the geometry (LatLonShape.java:61-68), and everyLatLonShapequery factory,newDistanceQueryincluded, takes aQueryRelation(LatLonShape.java:239-326). - History. LUCENE-8707 (
d48bafb2999, apache/lucene-solr#587, Ignacio Vera, 2020-02-19; 8.5.0) added the method with this one signature. #14534 (bb8b1397b01, jainankitk, 2025-05-06; 10.3.0), "Improve user-facing docs for geo package", added the example; its one review (an approval by jpountz, "Great!") and its one comment (about the commit message) do not discuss it. The only later commit on the file, #15874 (2026-04-01), does not touch it. - Precedent. #10088 (LUCENE-9046, "Fix wrong example in Javadoc of TermInSetQuery") and #12693 ("chore: update the Javadoc example in Analyzer", merged 2023-10-18) fixed wrong javadoc examples.
- Tests. No test compiles javadoc examples; #9534 (LUCENE-8488, open) asks for that in general.
The devil's-advocate check120 words
Strongest case for "intended" (built by the intended-behaviour checks and the refute review): javadoc <pre>{@code} blocks are uncompiled sketches that also leave out imports; the explicit relation is a deliberate API choice, shared by XYShape and LatLonPoint.newGeometryQuery; Circle is @lucene.experimental; and the error is loud and names the missing type.
Why it fails: a reader can supply missing imports, but not a missing mandatory argument. The defect is the example, not the API. @lucene.experimental warns that the API may change incompatibly, not that its current docs may be wrong. Loud means low impact, not intended. Every verifier and the adjudication rejected the "intended" reading; it stays at Low because it is a wrong API call, not a typo.
Recommended A. Add ShapeField.QueryRelation.INTERSECTS to the example's query line
Add the relation to the example's query line: Query query = LatLonShape.newDistanceQuery("location", ShapeField.QueryRelation.INTERSECTS, circle);. Javadoc only, one line. Validated: the patched example compiles, and the closest geo and shape suites, the format and static checks and the javadoc build pass.
--- a/lucene/core/src/java/org/apache/lucene/geo/Circle.java
+++ b/lucene/core/src/java/org/apache/lucene/geo/Circle.java
@@ -41,7 +41,7 @@
* Circle circle = new Circle(48.8584, 2.2945, 1000);
*
* // Create a query using this circle
- * Query query = LatLonShape.newDistanceQuery("location", circle);
+ * Query query = LatLonShape.newDistanceQuery("location", ShapeField.QueryRelation.INTERSECTS, circle);
* }</pre>
*
* @lucene.experimentalAll options and trade-offs3 options ยท 544 words
Two ways to resolve it; A is the smallest and was validated. A' is the same fix with the nested type imported; B removes the call instead.
Backport: the same diff applies to the 10.6.0 Circle.java (checked with a patch dry run). Upstream retired branch_10x on 2026-10-29 (#16911; 10.6 is the last 10.x minor, and bug fixes may still go to branch_10_6), so the targets are main and branch_11x, plus branch_10_6 if wanted.
A. Add ShapeField.QueryRelation.INTERSECTS to the example's query line (validated by the checks) (recommended)
Change Circle.java:44 to Query query = LatLonShape.newDistanceQuery("location", ShapeField.QueryRelation.INTERSECTS, circle);. Javadoc only, 1 line changed.
--- a/lucene/core/src/java/org/apache/lucene/geo/Circle.java
+++ b/lucene/core/src/java/org/apache/lucene/geo/Circle.java
@@ -41,7 +41,7 @@
* Circle circle = new Circle(48.8584, 2.2945, 1000);
*
* // Create a query using this circle
- * Query query = LatLonShape.newDistanceQuery("location", circle);
+ * Query query = LatLonShape.newDistanceQuery("location", ShapeField.QueryRelation.INTERSECTS, circle);
* }</pre>
*
* @lucene.experimentalTrade-offs
INTERSECTSmatches the method's own javadoc ("find all polygons that intersect a provided circle",LatLonShape.java:315); for indexed points it means "within 1 km".- The
ShapeField.QueryRelationspelling matchesLatLonPoint.newGeometryQuery's signature (LatLonPoint.java:328) and needs one more import,ShapeField, next to the imports the example already leaves to the reader. The adjudication and the cross-model reviews preferred it. - The line is 103 characters wide in the source; wrap it after
Query query =if you prefer 100 columns. The comment above it could also say what the query matches (not run; comment only).
What the checks validated
- Gradle, scratch worktree of
645d4fe14a20, seedDEADBEEF, 2026-11-01: without the fix the repro fails with assertions on and off; with the diff, the patched example block is line-for-line identical (5 lines) to the text compiled by the same test, and that test passes with assertions on and off. - Closest suites with the diff:
TestCircle,TestCircle2D,TestLatLonShape: 3 classes, 37 tests, 0 failures (1 skipped:testRandomPolygons, ignored upstream). ./gradlew :lucene:core:check -x testpasses (google-java-format, ecj lint, forbidden APIs, regeneration checksums; Error Prone skipped), and./gradlew :lucene:core:renderJavadocpasses with no warning lines in its log; the rendered page shows the corrected line.- At runtime the corrected call matches 1 of 2 points (500 m in, 5 km out), with assertions on and off (the hunt's control). The full Lucene test suite was not run (javadoc-only change).
Write Query query = LatLonShape.newDistanceQuery("location", QueryRelation.INTERSECTS, circle); (the finder's diff).
Trade-offs
- Shorter (92 characters), as
LatLonShape's own signature spells it. - The reader must import the nested type
org.apache.lucene.document.ShapeField.QueryRelation, which is less obvious than importingShapeField.
What the checks validated
Compile-checked: the same one test with this line passes 1 of 1 on main (2026-10-29).
Keep only the new Circle(...) line and add, in prose, "use it with {@link org.apache.lucene.document.LatLonShape#newDistanceQuery}".
Trade-offs
- Less to keep in sync. It fits rmuir's comment on #15225 (2025-10-25): "Code examples need to be kept extremely minimal in the rare cases where it does make sense: the maintenance cost is very high and we don't have great validation for these."
- Loses the one worked call; mikemccand suggested on the same issue (2025-11-13) correcting "any code examples that are stale".
What the checks validated
Not run.
No downstream runtime relevance: the broken example cannot compile, so no shipped application can contain it unrepaired.
Non-formal: an AI tool extracted the code examples from the javadocs of Lucene's core search, index and geo packages and compiled each against main; this one failed. A one-test repro, a scan of 159 core jars for the example's API members and runs on releases from 9.12.3 to 10.6.0 then dated it.
The method in full134 words
- A probe first compiled the block verbatim against the stock main
645d4fe14a20jars and got the error (2026-10-29). - The hunt unit re-ran it, extracted the block mechanically, wrote the one-test repro and checked in which of 159 core jars (every release from 1.9.1 to 10.5.2, the 10.6.0 RC1, branch_10x and main) the example's API members exist, with a class-file scan whose boundaries were cross-checked with javac: the two-argument call exists in none.
- A helper that compiles each version's own javadoc block dated the defect: no example on 9.12.3 and 10.2.2, the error from 10.3.0 on.
- A corrected-call control on a real index matched exactly the point inside the circle, with assertions on and off, so only the text is wrong.
- This is a compile check of documentation code, not model checking or a proof.
No prior report found in GitHub issues, PRs and commits, the JIRA archive, the mailing lists, downstream projects or the web (searched 2026-10-29, rechecked 2026-11-01). Nearest: #15225 (a general discussion of LLM-assisted and stale javadoc examples) and #9534 (a general wish to compile-check them). Not fixed upstream.
Searches3 searches
- Related, not this bug: #14534 (added the example; nobody discussed it); #15225 (open umbrella issue by jainankitk on LLM-assisted javadocs, whose body says the 10.3 geo docs were "created with the help of an LLM"; rmuir and mikemccand discuss costly or stale code examples in general terms; no comment names
Circle,newDistanceQueryor this error); #15356 (a follow-up geo docs PR, closed unmerged, not touchingCircle.java); #9534 (LUCENE-8488, open: compile-check javadoc examples in general); #12162, #10290 and #8205 (other geo items). - Not fixed upstream: upstream main
f815e679bf6c(2026-11-01) has the sameCircle.javaas645d4fe14a20;branch_10_6,branch_11xand the 10.6.0 tag still carry the two-argument call. Tracking issue #16937 does not name it. - Parallel javadoc sweeps: the open PR #16949 "Fix stale names and examples in javadocs" (27 files) and #16904 touch no geo file.
| Where | When | How | Found |
|---|---|---|---|
| apache/lucene issues, PRs and commits; the JIRA archive | 2026-10-29 | two scripted search runs (55 and 51 queries over identifiers, symptoms and the error text); 26 manual GitHub searches (apache/lucene, GitHub-wide and three downstream search engines); GitHub code search for the example text; the changed files of all 415 open PRs and of the 48 PRs updated since 2026-10-27 | no report; only apache/lucene and two forks carry the text, none corrected; no open PR touches Circle.java or LatLonShape.java |
| Mailing lists and web | 2026-10-29 | 33 queries over dev@, java-user@, issues@ and commits@; 9 web searches | no report; only the commits@ mirrors of #14534 |
| apache/lucene (recheck) | 2026-11-01 | upstream main HEAD and the file's commits; branch_10_6, branch_11x and the 10.6.0 tag at line 44; issues and PRs updated since 2026-10-29 for Circle javadoc, newDistanceQuery, QueryRelation, LatLonShape, geo javadoc and javadoc example; "Eiffel"; the files of #16949 and #16904; #16937 and #15225 re-read | no report: 0 hits; the 7 items matching "javadoc example" are other topics; the file is unchanged on upstream main f815e679bf6c |
Added broken by #14534 (bb8b1397b01, 2025-05-06) in 10.3.0; the method has needed a QueryRelation since 8.5.0 (LUCENE-8707), so the example never compiled. 9.12.3 and 10.2.2 have no example; 10.3.0 to 10.6.0 and main fail.
Versions tested5 rows
- API:
d48bafb2999(LUCENE-8707, apache/lucene-solr#587, Ignacio Vera, 2020-02-19; branch_8x50168ab5bc8, released in 8.5.0) addedLatLonShape.newDistanceQuery(String, QueryRelation, Circle...), its only signature ever. - Example:
bb8b1397b01(#14534, "Improve user-facing docs for geo package", jainankitk, author date 2025-05-06, merged 2025-05-07; branch_10xaf62580a673, the same author date; milestone 10.3.0) added theCircleclass javadoc with the example;git blamemaps lines 37-45 to it. - Since:
1518164afa3(#15874, 2026-04-01, a pattern-variable cleanup) is the only later commit on the file and does not touch the example. 10.3.1 to 10.5.1 have the sameCircle.javaas 10.3.0 and 10.5.2. 10.2.2 shipped after the merge but from branch_10_2, so it has no example; #14534 was never backported to 9.x.
| Version or commit | Verdict | Result |
|---|---|---|
main 645d4fe14a20 | affected | 1 error with assertions on and off (standalone and gradle); the patched example compiles with fix A |
10.6.0 (release tag commit 4ae946e5a9b) | affected | 1 error (the minimal test on the published jars; the version's own block on the same commit as RC1) |
10.5.2, branch_10x 657014b3c579 | affected | 1 error (the version's own block; the finder's and the independent reproduction's tests) |
| 10.3.0 | affected | 1 error (the version's own block; the minimal test on the published jars) |
| 10.2.2, 9.12.3 | not affected | no example in the Circle javadoc |
Confirmed by an independent reproducer, reviews by a reviewer from another model family (OpenAI GPT-5.6), an intended-behaviour devil's advocate and an adjudication (high confidence); an audit kept it as a low-priority doc defect. This doc's gradle run validated the fix.
Checks and verdicts294 words
Every check re-ran a repro on main or read the same block; none found a reading under which the example is meant not to compile.
| Check | Verdict | What it found |
|---|---|---|
| cross-model review, refute lens (OpenAI GPT-5.6, executing) | real, high confidence | Its own compile check failed with assertions on (two seeds) and off and on 10.5.2; its corrected INTERSECTS query on a real index matched exactly the one point inside the circle; the intended argument is weak. |
| independent reproducer | real | Its own test fails on main with assertions on and off, on 10.5.2 and on 10.3.0; its control with INTERSECTS compiles and counts 1 document (main and 10.5.2). |
| cross-model review, intended lens (OpenAI GPT-5.6, executing) | real, high confidence | The documented call is rejected; both corrected forms (imported and qualified relation) compile and the corrected query returns the expected hit; the intended argument is weak. |
| intended-behaviour devil's advocate | real, high confidence (documentation defect) | Built the three "intended" arguments and rejected each; re-ran the repro on main and 10.3.0; noted the InvalidSnippet scope. |
| adjudication | confirmed, high confidence, priority Low | Re-ran the independent reproduction's test with assertions on and off; kept at Low: a call to a signature that never existed, not a typo. |
| credibility audit | confirmed, Low | Re-ran the repro; impact minor confirmed as not inflated; one test, passes with the fixed line. |
| this doc's validation (2026-11-01) | fix A validated | Through gradle in a scratch worktree of 645d4fe14a20: the repro fails without the fix (assertions on and off); with fix A the patched example compiles, the 3 closest geo and shape suites (37 tests) pass, and :lucene:core:check -x test and renderJavadoc pass; the repro also fails on the published 10.6.0 and 10.3.0 jars. |
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 426 KB
Finding record, Lucene and upstream sources, repro files and diagram notes1,174 words
- Registry title
- geo.Circle's class javadoc 'Example usage' calls LatLonShape.newDistanceQuery("location", circle), but the only overload is newDistanceQuery(String, QueryRelation, Circle...), so the example has not compiled on any release since #14534 added it in 10.3.0 (documentation defect)
- Area
- core / geo (Circle class javadoc example)
- Priority
- Low, rank 1252: The geo.Circle example leaves out the QueryRelation argument, a single loud compile-time failure in the experimental geo-shape API since 10.3.0.
- Impact class
- minor
- Impact note
- Documentation only, with no runtime effect: a developer who uses the geo shape API (LatLonShape) and copies the only code example in the Circle class javadoc (Circle is @lucene.experimental) gets a compile error on every release since 10.3.0 and has to find the QueryRelation argument in the LatLonShape method signature; no configuration, scale or special input is involved.
- Summary
- The javadoc of org.apache.lucene.geo.Circle shows 'Example usage': make a circle of 1 km around the Eiffel Tower, then build a query with LatLonShape.newDistanceQuery("location", circle). Copied into code, that line does not compile on any release that has the example (10.3.0 and later), because the method has always needed a ShapeField.QueryRelation argument that says how indexed shapes must relate to the circle (for example INTERSECTS). With LatLonShape.newDistanceQuery("location", ShapeField.QueryRelation.INTERSECTS, circle) it compiles and matches a point 500 m from the centre but not one 5 km away, so only the javadoc is wrong.
- Introduced
- bb8b1397b01 (#14534 'Improve user-facing docs for geo package', by jainankitk, author date 2025-05-06, merged 2025-05-07T00:06Z, milestone 10.3.0; the branch_10x commit af62580a673 has the same author date): it added the Circle class javadoc with the 'Example usage' block, whose query line calls a two-argument newDistanceQuery(String, Circle) that has never existed. LatLonShape.newDistanceQuery has had exactly one signature, (String, ShapeField.QueryRelation, Circle...), since it was added by d48bafb2999 (LUCENE-8707, #587, by Ignacio Vera, 2020-02-19; branch_8x 50168ab5bc8, released in 8.5.0), so the example could not compile on the day it was written. The PR's one review (an approval, 'Great!') and one comment (about the commit message) do not discuss the example. The only later commit touching Circle.java, 1518164afa3 (#15874, 2026-04-01), does not change it [read: git log, git show and git log -S in the full-history clone; a bytecode scan of 159 core jars from 1.9.1 to main finds no (String, Circle) overload; exec: version runs, see affected_versions] (2025-05-06 (bb8b1397b01 and af62580a673, author date 2025-05-06T17:06:15-07:00 = 2025-05-07T00:06:15Z))
- First affected version
- 10.3.0 [exec] (the first release with #14534; 10.2.2, cut from branch_10_2 after the merge, has no example [exec])
- Affected versions
- 10.3.0, 10.3.1, 10.3.2, 10.4.0, 10.5.0, 10.5.1, 10.5.2, 10.6.0 (RC1 4ae946e5a9b), branch_10x 657014b3c579, branch_10_6, branch_11x f85446cb1af1 and main 645d4fe14a20; not affected: 10.2.2 and every earlier release (the Circle javadoc has no example; #14534 was never backported to 9.x). Not fixed upstream: main, branch_10x, branch_10_6 and branch_11x all still have the two-argument call at Circle.java:44 (2026-10-29). [exec: a version-faithful history helper, which compiles the example taken from each version's own Circle.java, reports no example on 9.12.3 and 10.2.2 and the same javac error on 10.3.0, 10.5.2, the 10.6.0 RC1, branch_10x and main, and compiles main's example once INTERSECTS is added; the finder's test fails on main (-ea and -da), 10.5.2, the 10.6.0 RC1 and branch_10x; the independent reproduction's test fails on main (-ea and -da), 10.5.2 and 10.3.0; the intended-behaviour check's on main (-ea and -da) and 10.3.0] [read: Circle.java at 10.3.1, 10.3.2, 10.4.0, 10.5.0 and 10.5.1 is byte-identical to 10.3.0 and 10.5.2, and LatLonShape keeps the same single overload]. 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 agreed, 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; the finder's, the independent reproduction's and the intended-behaviour check's searches and the adjudication's recheck agree): two scripted search runs (55 and 51 queries over GitHub issues, PRs and commits, downstream repositories, the dev@, java-user@, issues@ and commits@ lists, the JIRA archive and the web), 26 manual GitHub searches, GitHub code search for the example text (only apache/lucene and two forks carry it; no repository has a corrected copy), the changed files of all 415 open apache/lucene PRs and of the 48 PRs among the 61 items updated since 2026-10-27 (none touches geo/Circle.java or LatLonShape.java), 33 list queries and 9 web searches. Read but not the same bug: #14534 (added the example; nobody discussed it), #15225 (open umbrella issue on LLM-assisted javadocs that cites the 10.3 geo docs as its motivating example; maintainers say in general terms that code examples are costly to maintain and could be checked for staleness, but no comment names Circle, newDistanceQuery or this error), #15356 (a follow-up geo docs PR, not merged, not touching Circle.java), #9534 (LUCENE-8488, a 2018 wish to compile javadoc examples, naming none), #12162, #10290, #8205, and this week's outside javadoc-fix series (hidingmyname, Deepcodr, Lyin-OTTF, ant-tok; e.g. #16922), none of which touches geo/Circle.java. Recheck: six GitHub searches return no report ('Eiffel' 0 hits), no issue or PR was updated since a recent cutoff, and main 645d4fe14a20, branch_10x, branch_10_6 and branch_11x still carry the line. Tracking issue #16937 does not name it.
- Lucene commit tested
- main
645d4fe14a20: the minimal repro with assertions on and off, standalone and through gradle; the recommended fix in a scratch worktree (the patched example compiled through the same test; the closest geo and shape suites,:lucene:core:check -x testand:lucene:core:renderJavadoc). The minimal repro on the published 10.6.0 (release tag commit4ae946e5a9b) and 10.3.0 jars; the hunt's and the verifiers' tests on 10.5.2, the 10.6.0 RC1 and branch_10x657014b3c579; each version's own javadoc block compiled on 9.12.3 and 10.2.2 (no example), 10.3.0, 10.5.2, the 10.6.0 RC1, branch_10x and main.Circle.javais byte-identical on645d4fe14a20and on upstream mainf815e679bf6c(2026-11-01) (read).
- Finding record
lucene/core/src/java/org/apache/lucene/geo/Circle.java:37-47 (the example and @lucene.experimental) and lucene/core/src/java/org/apache/lucene/document/LatLonShape.java:315-319 (the only newDistanceQuery overload)
- The finding in 30 seconds
lucene/core/src/java/org/apache/lucene/geo/Circle.java (lines 37-47: the example and @lucene.experimental)lucene/core/src/java/org/apache/lucene/document/LatLonShape.java (lines 61-68 class javadoc, 315-319 the only newDistanceQuery)lucene/core/src/java/org/apache/lucene/document/ShapeField.java (lines 119-128, QueryRelation)lucene/core/src/java/org/apache/lucene/document/LatLonPoint.java (lines 296-297, 327-328) and XYShape.java (lines 252-253)build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/ErrorPronePlugin.java (line 531, InvalidSnippet)
- Who is affected
lucene/core/src/java/org/apache/lucene/geo/Circle.java (line 47)
- Why it looks unintended
lucene/core/src/java/org/apache/lucene/geo/Circle.java (line 37) and lucene/core/src/java/org/apache/lucene/document/LatLonShape.java (lines 61-68, 316-317)
- Suggested fix
lucene/core/src/java/org/apache/lucene/document/LatLonShape.java (line 315) and LatLonPoint.java (line 328)
- History
a Lucene clone tags releases/lucene/10.2.2, 10.3.0 and 10.6.0 (Circle.java: no example / blob c079b8000dd9 / blob c079b8000dd9)
- TestCircleJavadocExample.java (JUnit, one test):
repro/LFV-1019/TestCircleJavadocExample.java(63 lines)
Made from the code at 645d4fe14a20 and a probe executed for the diagram (the published example fails with the javac error; the corrected call compiles and matches the near point), in parallel with this doc.
assets/LFV-1019/bug.png(426 KB)
