spring-projects/spring-boot · error · IllegalStateException
'files' must not be null
Error message
'files' must not be null
What it means
ChangelogGenerator.buildRepository calls directory.listFiles(); if it returns null (the File is not a directory or an I/O error occurred), an IllegalStateException is thrown. The generator cannot proceed without a directory of jars to scan for spring-configuration-metadata.json.
Source
Thrown at configuration-metadata/spring-boot-configuration-metadata-changelog-generator/src/main/java/org/springframework/boot/configurationmetadata/changelog/ChangelogGenerator.java:67
}
private static void generate(File oldDir, File newDir, File out) throws IOException {
String oldVersionNumber = oldDir.getName();
ConfigurationMetadataRepository oldMetadata = buildRepository(oldDir);
String newVersionNumber = newDir.getName();
ConfigurationMetadataRepository newMetadata = buildRepository(newDir);
Changelog changelog = Changelog.of(oldVersionNumber, oldMetadata, newVersionNumber, newMetadata);
try (ChangelogWriter writer = new ChangelogWriter(out)) {
writer.write(changelog);
}
System.out.println("%nConfiguration metadata changelog written to '%s'".formatted(out));
}
static ConfigurationMetadataRepository buildRepository(File directory) {
ConfigurationMetadataRepositoryJsonBuilder builder = ConfigurationMetadataRepositoryJsonBuilder.create();
File[] files = directory.listFiles();
if (files == null) {
throw new IllegalStateException("'files' must not be null");
}
for (File file : files) {
try (JarFile jarFile = new JarFile(file)) {
JarEntry metadataEntry = jarFile.getJarEntry("META-INF/spring-configuration-metadata.json");
if (metadataEntry != null) {
builder.withJsonResource(jarFile.getInputStream(metadataEntry));
}
}
catch (IOException ex) {
throw new RuntimeException(ex);
}
}
return builder.build();
}
}
View on GitHub (pinned to 5b2dbdbb8b)
Solutions
- Verify the argument is an existing directory: `Files.isDirectory(Path.of(arg))`.
- Fix the path so it points to the folder containing the version's jar files.
- Ensure the directory is readable and mounted before invoking the generator.
Example fix
// before $ java -cp ... ChangelogGenerator 3.2.0 3.3.0 changelog.adoc # '3.2.0' is not a directory -> IllegalStateException // after $ ls 3.2.0 # confirm it is a directory of jars $ java -cp ... ChangelogGenerator 3.2.0/ 3.3.0/ changelog.adoc
Defensive patterns
Strategy: validation
Validate before calling
File dir = new File(args[i]);
if (!dir.isDirectory() || !dir.canRead()) {
throw new IllegalArgumentException("Argument must be a readable directory: " + dir);
}
File[] files = dir.listFiles();
if (files == null) throw new IllegalStateException("listFiles() returned null for " + dir); Type guard
boolean isValidMetadataDir(File f) {
return f != null && f.isDirectory() && f.canRead() && f.listFiles() != null;
} Try / catch
// ChangelogGenerator.main does not wrap this; if you embed buildRepository:
try { repo = ChangelogGenerator.buildRepository(dir); }
catch (IllegalStateException ex) {
if (ex.getMessage().equals("'files' must not be null")) {
// fix dir path and retry, or fail with a clearer message
} else throw ex;
} Prevention
- Validate both directory args with Files.isDirectory before calling the generator.
- Ensure the directories are mounted and readable in the run environment (CI).
- Use absolute paths to avoid ambiguity about the working directory.
When it happens
Trigger: Invoking ChangelogGenerator main with an argument that does not resolve to an existing, readable directory - e.g. the path is a file, does not exist, or is unreadable. listFiles() returns null exactly in those cases per its contract.
Common situations: Passing a wrong version directory path to the changelog generator; a missing/unmounted directory in CI; typo in the version number directory name; pointing at a path that is actually a jar rather than a folder of jars.
Related errors
- InputStream must not be null.
- Invalid layers.xml configuration
- Multiple '{}' nodes found
- Failed to read configuration metadata
- Invalid value for option '--environment'. Expected 'NAME=VAL
AI-assisted analysis of spring-projects/spring-boot@5b2dbdbb8b (2026-08-04).
Data as JSON: /data/errors/4c75b5126b9bd708.json.
Report an issue: GitHub.