Solr 9 modules

Solr 9 ships optional features as modules — separately loadable extensions. BOA seeds a fixed 17-file .mod set into a fresh Solr 9 install and enables five of them at the daemon level fleet-wide. The other twelve are present but load only when a core's solrconfig.xml references them.

How BOA deploys and enables modules

Seeding the .mod files. _if_fix_solr9_mod (solr.sh.inc) copies aegir/conf/solr9/* into /opt/solr9/server/modules/, guarded by [ ! -e "/opt/solr9/server/modules/ltr.mod" ] — it copies only when ltr.mod is absent, then sets root:root / 644 on the module files (chown root:root /opt/solr9/server/modules/* / chmod 644 …/*). The function is not called on every upgrade: its three call sites are all conditional — a symlink/mounted-disk host ([ -e /var/solr9/data ] && [ -L /var/solr9 ]), a fresh install (/var/solr9/data absent), and a version-bump upgrade (the solr-<VRN>-version.txt marker absent). On a standard non-symlink host already at the current Solr 9 version, a routine barracuda upgrade does not re-seed the .mod files, so operator edits under /opt/solr9/server/modules/ survive as long as ltr.mod is present.

Daemon-level enable line. Separately, on every Solr 9 pass BOA re-checks and restores the SOLR_MODULES auto-enable line and the Java path in /etc/default/solr9.in.sh (it greps for the exact strings and rewrites the block if absent). This is independent of the .mod seeding above.

The 17 deployed modules

The full set in aegir/conf/solr9/ (17 .mod files). The five marked auto-enabled are in BOA's SOLR_MODULES line and load at JVM startup fleet-wide; the rest load only if a core references them.

Module Purpose
analysis-extras.mod Auto-enabled. Extra analyzers (ICU normalisation, language-specific tokenisers)
analytics.mod Solr Analytics request handler
clustering.mod Auto-enabled. Carrot2 search-result clustering
cross-dc.mod Cross-datacentre replication primitives
extraction.mod Auto-enabled. Tika rich-document text extraction (Solr Cell)
gcs-repository.mod Backup target → Google Cloud Storage
hadoop-auth.mod Hadoop Kerberos auth integration
hdfs.mod Read/write index files from HDFS
jaegertracer-configurator.mod Jaeger distributed-tracing configurator
jwt-auth.mod JWT-based authentication
langid.mod Auto-enabled. Automatic language detection (Tika / OpenNLP)
llm.mod LLM integration
ltr.mod Auto-enabled. Learning-to-Rank ML
opentelemetry.mod OpenTelemetry observability
s3-repository.mod Backup target → S3
scripting.mod Script-based query / update logic
sql.mod Parallel SQL / JDBC query interface

What BOA actually enables

BOA writes:

# /etc/default/solr9.in.sh
SOLR_MODULES="analysis-extras,clustering,extraction,langid,ltr" # Auto-Enable Modules

These five load at JVM startup on every Solr 9 host (Excalibur, Daedalus, Chimaera), regardless of whether any core's solrconfig.xml references them — they are not zero-overhead. For typical Drupal-via-search_api_solr workloads the ones that do real work are usually:

  • analysis-extras — ICU normalisation for non-English sites.
  • extraction / langid — attachment indexing and language detection where used.
  • ltr — only where the codebase uses Learning-to-Rank scoring.

The remaining twelve are available but unloaded under standard workflows: they load JARs only when referenced by a core's solrconfig.xml, and operators can opt in per use case.

Two module-load paths

1. Daemon-level (SOLR_MODULES). Solr's startup reads SOLR_MODULES from /etc/default/solr9.in.sh and loads every named module node-wide. This is the five auto-enabled modules above.

2. Per-core (solrconfig.xml). A core pulls in module JARs explicitly:

<lib dir="${solr.install.dir:}/modules/analysis-extras/lib"/>
<lib dir="${solr.install.dir:}/modules/ltr/lib"/>

The twelve modules not in SOLR_MODULES incur cost only via this path — no reference, no load.

Localhost bind and jwt-auth

BOA binds Solr to localhost only (127.0.0.1:9099 for Solr 9, :9077 Solr 7, :8099 Solr 4); the external network is unreachable. Same-host Drupal sites connect over localhost; remote-Solr setups need explicit operator config plus a firewall opening. The jwt-auth module's value is correspondingly limited when nothing off-host can reach Solr.

Customising the module set

  • Add a module: drop a .mod file whose name is not in BOA's shipped set. The seeding copy only fires when ltr.mod is absent and never removes files it does not know about, so a custom .mod survives. Reference it from a core's solrconfig.xml via the solr_custom_config = YES route (Overview and tuning).
  • Force a re-seed of the shipped .mod files: remove a guard file (e.g. rm /opt/solr9/server/modules/ltr.mod) so the next qualifying pass copies the full set back, then run the upgrade.
  • Disable an auto-enabled module: edit the SOLR_MODULES line in /etc/default/solr9.in.sh — but BOA restores the exact string on the next pass, so any manual edit is reverted. Treat the five-module auto-enabled set as fixed; for a buggy shipped module, move its .mod aside or pin to a prior Solr version via _XTRAS_LIST, and document why.

Disabling unreferenced modules is pointless — the twelve non-SOLR_MODULES modules add zero JVM overhead until a core references them.

Related