New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Exclude empty starters jars and annotation processors when running or packaging with Maven and Gradle #22036
Comments
Hi, I tried testing the potential impact on startup times today on a simple app which includes I did so by using the following command to delete the starters from the fat jar:
So overall we can get rid of 6 starters here. Benchmarking this shows the following results compared to the normal baseline fat jar:
A relatively small, but yet visible impact. On my local machine the benchmark results were ranging between 50-100ms faster startup times for the excluded starter variant. Hope this helps. |
Another thought, we could leave them in the jar but exclude them from the classpath. |
Any particular reason why they should be in the JAR in the first place? #22030 is probably related. It would allow users to manually exclude them from being packaged easily. |
I'd prefer that we exclude them entirely. I think having jars in |
I'm fiddling around with that one and did the following for Gradle: --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootArchiveSupport.java
+++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootArchiveSupport.java
@@ -195,6 +195,7 @@ class BootArchiveSupport {
if (this.excludeDevtools) {
excludes.add("**/spring-boot-devtools-*.jar");
}
+ excludes.add("**/spring-boot-starter-*.jar");
this.exclusions.setExcludes(excludes);
} The problem that I'm seeing here is that we might exclude starters that are not from Spring-Boot itself, but rather external starters that are prefixed with spring-boot-starter. I would say this is a rather common naming pattern. Unfortunately, we don't have the group information available here to the best of my knowledge in order to narrow that down. Possibly we have to get a list of all spring-boot owned starters here to only exclude those. Thoughts? We probably need this for the maven part anyhow, which I would personally configure in In case you generally agree with my approach, I'm happy to work on a PR for that. |
My gut instinct is that we won't be able to use the jar name alone to determine if we can exclude it or not. We probably also need to inspect that jar during the build to find out if it's empty (or nearly empty). We could perhaps add something to the META-INF/MANIFEST.MF file of the starters to do indicate there's nothing of value in it. |
I'm playing around on the Gradle side of things so far in this branch. Probably tomorrow I'll play around with the Maven part by filtering the JARs in a similar way inside the |
I've done the same for Maven now in the mentioned branch. In case you think this is a valid solution I would give this a cleanup and introduce a EDIT: Update the branch in place with the |
This commit updates the Maven Plugin to filter dependencies based on the Spring-Boot-Jar-Type entry in their manifest. Jars with a Spring-Boot-Jar-Type of dependencies-starter or annotation-processor are excluded. See gh-22036
This commit updates the Gradle Plugin to filter dependencies based on the Spring-Boot-Jar-Type entry in their manifest. Jars with a Spring-Boot-Jar-Type of dependencies-starter are excluded. Unlike the Maven plugin, jars with a type of annotation-processor are not excluded. It is not necessary with Gradle as use of the annotationProcessor configuration for such dependencies already ensures that they are not included. See gh-22036
Jars with a |
I've just tested this in M4 and it doesn't seem to work. For example both |
@OrangeDog Are you maybe using Maven and have you switched the maven plugin to M4 as well? I can't reproduce the behaviour with the mentioned version. |
As far as I can tell
|
If I generate a fresh example via https://start.spring.io/ including |
I can't share my current project, but I've removed everything non-standard-looking from the pom and it still includes everything. I've not had much luck working out why, but it also doesn't work on the final 2.4.0 release. |
@OrangeDog @dreis2211 I am having similar issues using 2.4.1. I have two projects which use the same starters. In one project, all starters are included in the runnable jar, in the other project, none are included (as expected). I haven't had much luck figuring out the cause either, and they appear to be configured the same way. It would help if the spring-boot-maven plugin would output some debug information when using |
@edwardsre make sure that both projects use version |
@snicoll I have verified both projects are using the same version of the plugin |
@odrotbohm brought up the interesting idea that we could simply exclude empty starter JARs from our fat jars. This might help performance when searching for missing classes.
The text was updated successfully, but these errors were encountered: