skip to content

What is the danger of a partially-built index across a multi-jar classpath, and how does spring.index.ignore relate to it?

level: seniorimportance: nice to knowfreq 8%

answer

  1. auto-enabled by any spring.components present
  2. un-indexed jar -> beans silently missing
  3. fix: index all modules OR disable
  4. spring.index.ignore=true (sysprop or spring.properties)
  5. loadIndex returns null when ignored

basics

~20 s

If only some jars ship a spring.components file, Spring still switches to index mode, but components in the un-indexed jars can be missed. To be safe you either index every module or set spring.index.ignore=true to force full scanning everywhere.

solid answer

~40 s

The index is auto-enabled by the mere presence of any META-INF/spring.components on the classpath. In a multi-module or multi-jar application, if some artifacts were built with the indexer and others weren't, the merged CandidateComponentsIndex is incomplete: beans in the un-indexed jars aren't recorded, so index-mode scans can silently miss them. The safe options are (1) build the index for the whole application so it's complete, or (2) disable it globally with the spring.index.ignore property — set as a JVM system property (-Dspring.index.ignore=true) or in a spring.properties file at the classpath root. When ignored, Spring reverts to full runtime scanning. This is the main correctness gotcha of the feature: partial coverage plus auto-enable can hide beans.

code

java · 9 lines
java
// Force full runtime scanning regardless of any spring.components on the classpath:
// Option A - JVM system property:
//   java -Dspring.index.ignore=true -jar app.jar

// Option B - spring.properties at the ROOT of the classpath (src/main/resources/spring.properties):
//   spring.index.ignore=true

// With either set, CandidateComponentsIndexLoader.loadIndex(classLoader) returns null
// and Spring reverts to classpath scanning.

go deeper

for a junior

Aware that indexing must cover everything or beans can be missed.

for a middle

Explain auto-enable-by-presence and that un-indexed jars aren't scanned in index mode.

for a senior

Name spring.index.ignore, where to set it, and the two safe resolutions.

for a principal

Treat it as a classpath-hygiene/build-governance concern across modules and third-party jars; define a policy (index all or none).

## Why partial indexing is dangerous The index is turned on **automatically** the moment `CandidateComponentsIndexLoader` finds any `META-INF/spring.components` resource. But an application classpath is usually many jars: your modules plus third-party libraries that also define Spring components. The processor only indexes the sources it compiles, so a jar built **without** `spring-context-indexer` contributes **no** entries. When Spring runs in index mode, an index-supported scan asks the merged `CandidateComponentsIndex` for candidates in a base package. If a library's components were never indexed, `getCandidateTypes` simply doesn't return them — the beans are **silently missing**. Unlike a full ASM scan (which reads whatever is actually on the classpath), the index only knows what was recorded at build time. So mixing indexed and un-indexed jars scanned under the same base packages can drop beans without any error. ## The two safe outcomes 1. **Make the index complete** — ensure every module that contributes scanned components is compiled with the indexer, so `spring.components` covers all of them. 2. **Turn the index off** — set the property **`spring.index.ignore`** to `true`. This is read via `SpringProperties`, so you can set it either as a JVM system property `-Dspring.index.ignore=true` or place `spring.index.ignore=true` in a `spring.properties` file at the **root of the classpath**. With it set, `CandidateComponentsIndexLoader.loadIndex` returns `null` and Spring falls back to full runtime scanning everywhere — correct but not accelerated. ## Practical guidance - Most third-party Spring libraries do **not** ship an index and rely on being scanned normally; but they're usually not under your `@ComponentScan` base packages, so they're picked up via auto-configuration/imports instead. The real risk is your own multi-module build where some modules index and some don't. - If you enable indexing, enable it **consistently** across all modules whose components you scan. - If you ever see beans mysteriously absent only after adding the indexer, suspect partial coverage and try `spring.index.ignore=true` to confirm.

  • You added the indexer to one module of a multi-module app and some beans vanished. What happened and how do you fix it?
    The index auto-enabled globally but only covers the one indexed module, so components in the un-indexed modules aren't recorded and get missed. Fix by indexing all scanned modules, or set spring.index.ignore=true to fall back to full scanning.

saying these in an interview costs you the question

  • Assuming a partial index is automatically merged with a live scan of the rest
  • Not knowing the index is auto-enabled by presence alone
  • Inventing a spring.index.enabled property (only spring.index.ignore exists)
  • Thinking missing beans would raise an error rather than silently disappear

context