Skip to content
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

Option for light(er)weight packaging #1813

Closed
fastnsilver opened this issue Nov 3, 2014 · 22 comments
Closed

Option for light(er)weight packaging #1813

fastnsilver opened this issue Nov 3, 2014 · 22 comments
Labels
status: declined A suggestion or change that we don't feel we should currently apply

Comments

@fastnsilver
Copy link

First of all Spring Boot is awesome. What might make it even more awesome? Have the Maven plugin package a .jar without all the dependencies; resolving them at first run. See https://github.com/puniverse/capsule. Perhaps Spring Boot could provide a flag for doing such?

@joshlong
Copy link
Member

joshlong commented Nov 3, 2014

Hmm - Isn't that just a .jar? Just comment out the build plugin and do mvn dependency:copy-dependencies and then make sure the jar has those libs on the CLASSPATH. Or is hat last bit what you're after?

@joshlong
Copy link
Member

joshlong commented Nov 3, 2014

Oooh - just looked at capsule. I dig it! That would be cool..

@thomasdarimont
Copy link

Interesting - what happens if some dependencies can't be resolved?
I guess in this case you'd end up with a broken app...

But the idea is really interesting - you could also use that or automatic update checks at startup...
Regarding spawning a new JVM, can you also plug something in like: drip?https://github.com/ninjudd/drip

@fastnsilver
Copy link
Author

How often are you NOT able to resolve an artifact? A good deal of time (on build) is due to config and/or networking. Yes, there is chance of a broken app (when dependencies aren't completely resolved), but isn't that something that a smoke test or test run after deployment would catch? I'm just thinking out loud here.

@philwebb
Copy link
Member

philwebb commented Nov 4, 2014

Someone actually started a contribution for this (see https://github.com/patrikbeno/spring-boot/blob/MvnLauncher/spring-boot-docs/src/main/asciidoc/mvnlauncher.adoc). We had a brief email conversation and this was my response at the time:


Providing on-demand download support is something that we have considered in the past and I think it is an interesting approach, however, I have a few reservations. My primary concern is that packaged applications become much more brittle when they need to download dependencies during production deployment. Do you find the larger self-contained JARs problematic? Is the main goal to reduce duplication by allowing multiple applications to share the same download cache? Does your operations team like the approach?

I think it would be worth trying to find a way to support the MvnLauncher without needing to add too many additional classes to the spring-boot-loader project. Since classes from spring-boot-loader get repackaged into use projects I’m very keen to keep its size fairly small. I’m not sure that on-demand loading will be something that the majority of users will want to use (although I’m happy to be proved wrong if we get enough votes for the feature) so I’d like to not impact people who might not want it.

@philwebb
Copy link
Member

philwebb commented Nov 4, 2014

I still feel that on-demand downloading is a risky thing to support out of the box.

@odrotbohm
Copy link
Member

odrotbohm commented Oct 1, 2016

The actual problem caused with fat-JAR deployments is that — especially if the end of you CI pipeline installs the artifact into a repository — you basically accumulate a lot of artifacts that have other artifacts wrapped in them. Other artifacts that are actually also available in the repository.

What if the resolution process was something to opt in via e.g. a command line flag and you could express that you might want to run the resolution against a well known local folder (e.g. .m2/repository only)? /cc @ewolff

@ewolff
Copy link

ewolff commented Oct 1, 2016

In addition it would be great if such a .m2/repository could be created by Spring Boot.

@odrotbohm
Copy link
Member

I guess we' have to use means to invoke Maven (or $buildSystem in general) for the artifact resolution. Manually replacing artifacts in an already existing repository is probably a tricky thing, esp. considering that multiple of those resolutions could run in parallel.

I know that the actual list of dependencies could be precomputed so that the calculation doesn't have to be done at resolution time but even downloading manually those artifacts might cause issues with the artifact metadata (or we'd have to replicate the update of that metadata, which is even worse).

@ewolff
Copy link

ewolff commented Oct 1, 2016

Maybe I wasn't clear. I imagine mvn spring-boot:package-dependencies would give me all dependencies needed in a single repository.zip that I could unpack on a machine to prepare it for the application.

When I start the application java -jar myjar.jar it should somehow use them and download additional artifacts if needed. That way I can prepare a Docker base image that already includes the dependencies.

@odrotbohm
Copy link
Member

Where'd you store the packaged ZIP then? Wouldn't (that have to) be deployed into the repository, too?

@ewolff
Copy link

ewolff commented Oct 1, 2016

I'd extract it into the Docker base image.

@philwebb philwebb added type: enhancement A general enhancement and removed status: waiting-for-triage An issue we've not yet triaged labels Oct 3, 2016
@dsyer
Copy link
Member

dsyer commented Oct 18, 2016

I had a look at this and threw together something that works. It could be tidied up a bit, but it seems like a useful direction: https://github.com/scratches/launcher.

@dsyer dsyer added the for: team-attention An issue we'd like other members of the team to review label Oct 18, 2016
@philwebb philwebb removed the for: team-attention An issue we'd like other members of the team to review label Nov 2, 2016
@wilkinsona
Copy link
Member

If we're going to do something with lighter weight packaging, @dsyer's thin launcher looks to be the way to go. Before we can consider making it part of Boot we need to get some feedback on it. So, if you're interested in this functionality, please check out what Dave has done and let us know how well it works for you.

@odrotbohm
Copy link
Member

I've just added the thin launcher to a branch in Spring Restbucks. Very easy setup, works just fine. However, I couldn't get any output about what it's doing using the advertised command line flags and filed a ticket.

@fastnsilver
Copy link
Author

fastnsilver commented May 18, 2017

Really nice work @dsyer! You considered and solved for quite a few more use cases than I had originally thought of. I will definitely recommend this packaging approach going forward. Seems like it should be baked into Spring Boot Maven Plugin rather than as a separate dependency. But I certainly understand why.

I like that you can target a Maven repo with thin.root. One thought occurred to me... and that's if a settings.xml in that location refers to an artifact management repository, like Nexus or Artifactory (that is responsible for resolving "in-house/private" artifacts). If you happen to deploy an artifact (e.g., executable .jar), that has dependencies on "in-house" artifacts, to a target deployment environment (e.g., VM or container), some care should be taken. I'm thinking of a scenario where e.g., Artifactory resides in a separate (potentially unreachable) network than where the artifact will be running. In that case some kind of mirroring or proxying must be setup in the target environment to minimize exposing any "ip". << Definitely outside the concern of this implementation.

That said I see you can enable thin.dryrun so if you package your .jar in a container you could run this first when packaging. So, the result is that you have all the dependencies baked into your image anyway, just in a Maven repo, and not in your "thin jar". Looks like you are doing something similar in the fork of java-buildpack for Cloud Foundry.

@dsyer
Copy link
Member

dsyer commented May 19, 2017

@fastnsilver I believe your settings.xml should work out of the box (we use the maven libraries to resolve dependencies). Try it and post a new issue in the thin-launcher repo if not.

@philwebb
Copy link
Member

Closing this one in favor of the thin jar launcher

@statsmind
Copy link

thin plugin is great, but, most of my projects are multi-module ones, I don't want to deploy the project modules to a private maven repository, is there any way I can pack the project-module jars into the thin jar?

@philwebb
Copy link
Member

philwebb commented Jan 4, 2021

@jameshugit You'd have to raise a request at https://github.com/spring-projects-experimental/spring-boot-thin-launcher/issues

@dsyer
Copy link
Member

dsyer commented Jan 4, 2021

Like spring-projects-experimental/spring-boot-thin-launcher#78 or spring-projects-experimental/spring-boot-thin-launcher#15 (ie no need for a new issue there).

@Kylin824

This comment was marked as duplicate.

humaolin pushed a commit to humaolin/spring-boot that referenced this issue May 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: declined A suggestion or change that we don't feel we should currently apply
Projects
None yet
Development

No branches or pull requests