spring-projects-experimental / spring-boot-thin-launcher

Tools for building "thin" executable jars, with a focus on, but not exclusively for, Spring Boot
https://github.com/dsyer/spring-boot-thin-launcher
Apache License 2.0
681 stars 90 forks source link

"hybrid" mode to inline some jars into thin jar #15

Open linux-china opened 7 years ago

linux-china commented 7 years ago

if snapshot jars are not inlined into thin jar, the app could be different after startup because of snapshot jars changed in local maven repository. it's not good for integrated testing and deployment in testing environment. could thin launcher add a configuration to inline some jars?

dsyer commented 7 years ago

It's possible. Someone else asked about a "hybrid" mode where you could resolve jars from the archive if they were there (snapshot or not).

Regarding snapshots specifically, I guess I disagree though, because the point of snapshots is that they change, so fixing the contents is kind of the wrong thing to do IMO. On the other hand I see no reason why you shouldn't be able to do it if you want to.

linux-china commented 7 years ago

hybrid mode is ok for me. :)

linux-china commented 7 years ago

Now I use maven shade plugin to add some jars, and I could add /BOOT-INF/lib/ into classloader by thin launcher?

<plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <id>copy-dependencies</id>
                        <phase>prepare-package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <includeArtifactIds>
                                commons-lang3
                            </includeArtifactIds>
                            <outputDirectory>${project.build.directory}/classes/BOOT-INF/lib/</outputDirectory>
                            <overWriteReleases>false</overWriteReleases>
                            <overWriteSnapshots>false</overWriteSnapshots>
                            <overWriteIfNewer>true</overWriteIfNewer>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
dsyer commented 7 years ago

I'm not really sure what the question is. This ticket is about a new feature that might take shape in the thin launcher. If you have an existing fat jar, you can launch it with one of the other launchers.

joshlong commented 7 years ago

Revisiting this a bit more - it would also be useful to have some sort of hybrid mechanism to inline local dependencies where the user has artifacts that are in the local .m2 but not available in maven central / jcenter. Oracle's older drivers are sometimes hard to locate. Old JCP impls. And any number of other quirky dependencies you'd find in a typical enterprise.

Also, in continuous delivery it's common to never 'release' software. You're always using SNAPSHOTs, since in theory you could deploy many times a day (or hour!) and going through the mvn release dance isn't for the faint of heart. So, having a way to inline certain dependencies relative to build time would also be useful.

blaluc commented 6 years ago

It's still not clear to me if, with the current spring-boot-thin-tools-converter, is possible to produce a "semi-fat" jar, where only some specific libraries are included in the jar while the others are resolved and downloaded from the repo. Could you help?

dsyer commented 6 years ago

This issue is still open. What's unclear about it?

blaluc commented 6 years ago

It's my fault. I didn't catch if the spring-boot-thin-tools-converter already covered this feature somehow. I will stay tuned for the 'hybrid' mode. Thanks for the reply and for the great job you're doing.

horschi commented 5 years ago

I would also be interested in hybrid mode.

huyangcheng commented 2 years ago

Do you plan to update?

werner77 commented 10 months ago

Upvote for this issue. The mentioned thin.libs option does not work because the jars included there are put at the end of the classpath instead of at the front.

Currently I use this approach which is far from optimal:

Surely this is a far from optional approach. I did not know how to bundle jars inside the main jar and add them to the classpath. I'm not sure the BOOT-INF/lib folder works with the thin launcher?

dsyer commented 10 months ago

Unless I'm missing something you would have the last 3 steps even if thin.libs worked a bit differently. IMHO it's a bad idea to rely on classpath ordering to prioritize features, so I'm also not really sure why that matters here. All you really need is to exclude those dependencies from the thin.properties (or the pom.xml whichever you are using), right? I thought maybe the build tools could do that.

And no, there is no BOOT-INF/lib in this model. I suppose there could be, but then it wouldn't really be a thin jar. It would also add some complexity to the launcher.

werner77 commented 10 months ago

@dsyer Thanks so much for the response.

For clarity, I'm talking about the internal dependencies (modules) in a multi-module project. Those dependencies should preferable be bundled within the lib to ensure their version is pinned to the compiled version and not every team has an internal maven repository set up for this purpose. Obviously those dependencies are visible via the pom, because they are defined within the project. There is no way to exclude dependencies from the thin.properties file out of the box unless I'm mistaken?

It would make a ton of sense in my opinion to build on the Jar loader of Spring to support this BOOT-INF model as it would solve all the issues I and others struggling with this feature have. Basically just appending the external dependencies that are not within the jar itself where the dependencies within the jar always take precedence. Also the resolver could/should exclude these dependencies. Solves all kind of issues with repository authentication etc (see the issue I created where I get 401 in case a thin.properties file is present for my Artifactory repository).

Also in my opinion, (in general) if you can add items to the class path, it makes sense to give them precedence to be able to override the pom versions. You almost never want to do it the other way around?

werner77 commented 10 months ago

By the way, thanks a lot for this project as it was the only way to get around the 512 MB file size that AWS elastic beanstalk imposes.

werner77 commented 10 months ago

See the PR I just created: https://github.com/spring-projects-experimental/spring-boot-thin-launcher/pull/207