Merge properties files with the same path in the merged module instead of overwriting them - #370
Open
bjorndarri wants to merge 1 commit into
Open
bjorndarri wants to merge 1 commit into
bjorndarri wants to merge 1 commit into
Conversation
…d of overwriting them When several non-modular jars contained a properties file with the same path, each jar unpacked into the merged module overwrote the file from the previous one, so only one of them survived. Which one depended on the file system listing order. Frameworks that discover resources via ClassLoader.getResources(), such as JasperReports with its jasperreports_extension.properties, then silently lost registrations. Properties files with the same path are now appended to each other, the same way META-INF/services files are merged (beryx#124). Identical files are kept once. Conflicting keys resolve to the value from the jar whose name comes last, and a warning lists them. The jars are merged in name order, so the result no longer depends on the file system.
bjorndarri
force-pushed
the
merge-properties-files
branch
from
September 13, 2026 11:56
c97b52f to
c22af1b
Compare
bjorndarri
marked this pull request as ready for review
September 13, 2026 12:31
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Hey there,
I've been working around this issue for quite a while, by using the extra-java-module-info plugin, see https://github.com/codion-is/chinook/blob/main/buildSrc/src/main/groovy/chinook.jasperreports.pdf.modules.gradle.
I figured it was time to see if Claude could help me solve this, which it did.
Below you'll find Claude's analysis and solution.
Problem
Several non-modular jars can contain a
.propertiesfile at the same path.prepareMergedJarsDirunpacks the jars one after another, so each file overwrites the one before. Only one survives, and which one depends on the order the file system listsnonmodjars.Frameworks that find registrations through
ClassLoader.getResources()silently lose entries. For example, in JasperReports 7jasperreportsandjasperreports-pdfare both automatic modules, and both shipjasperreports_extension.properties. The merged module keeps only one of them, with no warning:Which of the two happens can change with nothing more than a version upgrade. On ext4, a directory lists files in an order computed from their names and a per-filesystem seed, so the version in the jar names alone can flip the merge order. Here's what happened when the jar names were created in a fresh directory on the same disk:
Fix
META-INF/servicesfiles have been merged since IIORegistry lookup #124. Identical files are kept once.Compatibility
When no keys conflict, the merged file has everything the surviving file had before, plus the entries that used to be dropped. When keys conflict, the jar names now decide the winner instead of file system order, and the build logs it. To keep only one jar's file, use
jarExclude("other-lib", "config.properties"), now documented in the user guide.Tests
MergedPropertiesSpeccreates two jars with clashingextension.propertiesfiles, builds and runs an image, and checks that both sets of keys are visible. It fails onmaster.--type rpmtests, which fail the same way onmasteron machines withoutrpmbuild.jasperreports_extension.propertiescontains core's 11 registry factories plus the pdf one.