Repository navigation
Support provided-scope libraries when extracting an executable war - #51372
Conversation
|
Note on the red build: the failure is MongoDB 5.9.2 has been published since #51339 bumped the BOM to 5.9.1, so the check flags the drift on any build until that's bumped again. This PR only touches Happy to rebase once that lands if you'd like a green run before reviewing. |
|
@philwebb What do you think about adding a new manifest attribite for the |
|
@mhalbritter that reads better to me than the constant, and I'm happy to redo it that way — it would let the jarmode stop knowing war layout at all, which is really the underlying smell here. One fact that may make the decision easier: the tools jarmode is packaged into the archive it operates on — Shape I'd propose unless you'd rather something else:
That's a wider change than this PR, touching |
|
I like the proposal. I agree with @mhalbritter that it's better than hardcoding the location. |
|
@skdas20 you can go ahead, please implement adding a new manifest attribute for the lib-provided dependencies, which the jartools can then read. |
5c14f66 to
40e4e83
Compare
|
Thanks @mhalbritter, @philwebb — pushed, and the hardcoded
String libraryLocation = getLayout().getLibraryLocation("", LibraryScope.COMPILE);
putIfHasLength(attributes, BOOT_LIB_ATTRIBUTE, libraryLocation);
String providedLibraryLocation = getLayout().getLibraryLocation("", LibraryScope.PROVIDED);
if (!ObjectUtils.nullSafeEquals(providedLibraryLocation, libraryLocation)) {
putIfHasLength(attributes, BOOT_LIB_PROVIDED_ATTRIBUTE, providedLibraryLocation);
}The comparison against the compile location is doing real work rather than being defensive:
Gradle plugin: As mentioned, no fallback for older archives is needed since Green locally: |
See spring-projectsgh-51372 Signed-off-by: Sumit Kumar Das <151006536+skdas20@users.noreply.github.com>
40e4e83 to
f830fc8
Compare
…e war" Make the extracted war runnable with java -jar: move root content such as static files and JSPs to META-INF/resources/, name the application jar *.jar, and write the META-INF/ directory entry before the manifest. Fail early when a library and a provided library share a file name, as both would be extracted to the same location. Assert the Spring-Boot-Lib-Provided attribute in the Maven and Gradle tests and document war extraction. See spring-projectsgh-51372
…e war" Make the extracted war runnable with java -jar: move root content such as static files and JSPs to META-INF/resources/, name the application jar *.jar, and write the META-INF/ directory entry before the manifest. Fail early when a library and a provided library share a file name, as both would be extracted to the same location. Assert the Spring-Boot-Lib-Provided attribute in the Maven and Gradle tests and document war extraction. See spring-projectsgh-51372
f830fc8 to
1dd4bee
Compare
|
Thanks @skdas20 ! |
See gh-51367.
Problem
IndexedJarStructure.toStructureDependencyflattens every classpath index entry relative to the singleSpring-Boot-Liblocation:For an executable war
Spring-Boot-LibisWEB-INF/lib/, but provided-scope dependencies (the embedded container among them) are packaged underWEB-INF/lib-provided/byLayouts.Warand are listed inWEB-INF/classpath.idxalongside the rest. The first such entry trips the assertion, so-Djarmode=tools extractfails withInvalid library location WEB-INF/lib-provided/...on any war built from awebstarter.Only
Spring-Boot-Libis recorded in the manifest, so the second location can't be read from there.WarLauncherhas the same need and hardcodes both:Change
Accept entries from either location when flattening, mirroring
WarLauncher, and keep the failure for anything genuinely outside a library root (now an explicitIllegalStateException, since the two-location check no longer fitsAssert.state).Tests
Added to
IndexedJarStructureTests, using a war-shaped manifest and an index containing both aWEB-INF/lib/and aWEB-INF/lib-provided/entry:shouldResolveLibraryEntryFromWarProvidedLocation— the provided entry resolves as aLIBRARYflattened to its bare jar nameshouldCreateLauncherManifestForWarWithProvidedLibraries— both jars appear in the generatedClass-PathBoth fail on
main:With the change the module's tests and
checkFormatMain/checkFormatTestall pass.One thing worth your call: I hardcoded the location as a constant to match
WarLauncher. If you'd rather it be derived (or carried in the manifest as a new attribute so the tools jarmode doesn't need to know war layout at all), happy to redo it that way.