Hi all,

To be clear up front: I experimented against Lucene main — the unreleased
line that will become 11.0 — not a released version.

With 11 starting to come up on the Lucene dev list (the Java 25 baseline
has already landed on main, and folks have floated whether to just release
11), curiosity got the better of me and I took the Solr side for a spin in
my garage to see how big the eventual upgrade will be.

It felt worth Solr getting a read on it now rather than scrambling after 11
drops.

That turned into something concrete: Solr compiles and passes "check" (and
the affected test suites) against a locally-built Lucene main
(11.0.0-SNAPSHOT) on Java 25.

Before taking it further I want to check nobody is already on this, and get
direction on the two decisions the upgrade forces.

What the port involves: the API migration is large but mechanical — ~290
compile sites across solr-core (+ analysis-extras and tests), all tracking
documented Lucene 11 removals/renames: CollectionStatistics/TermStatistics
-> FieldStats/TermStats, PriorityQueue's new LessThan constructor,
DocIdSet/LeafReader signatures that dropped "throws IOException",
WildcardQuery/RegexpQuery losing the determinize-work-limit arg,
SortField.setMissingValue -> constructor, TopGroups.merge taking a List,
and so on. No architectural surprises.

Decision 1 — the Java 25 baseline.

Lucene 11 ships Java 25 bytecode, so Solr can't even consume it until
Solr's minimum JDK is 25 (we're on 21).

That's a project/policy call, not a code one — is there appetite to make
that move aligned with Lucene 11, and on what timeline?

(Our Docker base image is already on temurin:25, so the runtime side is
largely there.)

Decision 2 — compound-file config.

Lucene 11 removed the merge-policy maxMergeAtOnce and noCFSRatio settings,
and moved compound-file selection onto the codec's CompoundFormat.

Two user-facing consequences:

(a) a solrconfig.xml still setting those merge-policy options would fail
core init — in my branch I made Solr ignore-with-warning instead, so
existing configs keep loading. Is warn-and-ignore the behavior we want, or
should it hard-fail with a migration message?

(b) useCompoundFile no longer reaches merged segments on its own (only
flushed ones), so I bridged it to the codec and added a maxCFSSegmentSizeMB
option as the noCFSRatio replacement. Sanity-check welcome on that approach.

On timing: this is entirely gated on Lucene 11, which is a Lucene call, not
a Solr one — so I'm not asking anyone here to commit to a date.

What made me look now rather than later: the Java 25 baseline has already
landed on Lucene main (minJava=25, Gradle 9, Version.LATEST = 11.0.0), the
10.x line looks like it's winding down, and 11 has come up on the Lucene
dev list a couple of times.

If anyone here follows the Lucene side closely and has a rough read on
whether 11.0 is nearer-term or further out (and whether a 10.6 lands
first), that would help me decide whether to keep this warm or park it
until it's real.

The work is a clean stack of five commits (build wiring / mechanical API
port / merge-policy tolerance / compound-file control / changelog) so it's
reviewable in pieces, on a branch here:
https://github.com/serhiy-bzhezytskyy/solr/tree/lucene11-upgrade-experiment

It's an experiment branch — it builds against a locally-published Lucene
main via mavenLocal, so the version-pin/lock bits are scaffolding I'd drop
for a real PR.

Happy to open a JIRA + PR once 11.0 is released and there's a direction on
the Java-25 question — or to hand the port off if someone's already on it.

A small part of this doesn't need to wait for 11.

I checked each change against the Lucene version it first becomes available
in (10.4 = what we're on, 10.5, 10.6/branch_10x).

Most of it is 11-only by design, but a couple compile against current main
today:

change                                               10.4  10.5  10.6
11-only

---------------------------------------------------------  ----  ----
-------

SortField.setMissingValue -> constructor arg         yes   yes   yes   no

Operations.concatenate(a,b) -> concatenate(List)     yes   yes   yes   no

ScalarEncoding import move                           no    yes   yes   no

PriorityQueue -> LessThan constructor                no    no    no    yes

CollectionStatistics/TermStatistics -> FieldStats    no    no    no    yes

TopGroups.merge(array -> List)                       no    no    no    yes

WildcardQuery/RegexpQuery drop determinizeWorkLimit  no    no    no    yes

DocIdSet/LeafReader de-throws, LUCENE_9_x consts     no    no    no    yes


So the first two rows are adoptable now — I verified they build against
current Solr main (on Lucene 10.4).

If there's interest I'm happy to split them into a small "prep for Lucene
11" PR separate from the version bump.

It's a small win though: setMissingValue isn't deprecated on 10.x, so it's
forward-compat prep with no standalone value, and as the table shows the
bulk (the stats rename and friends) can't move until 11 since the new
classes don't exist in 10.x.

Mostly I'm sharing the table so the scope is clear.

Thanks,

Serhiy

Reply via email to