spring-boot-thin-launcher icon indicating copy to clipboard operation
spring-boot-thin-launcher copied to clipboard

"hybrid" mode to inline some jars into thin jar

Open linux-china opened this issue 8 years ago • 15 comments

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?

linux-china avatar May 19 '17 06:05 linux-china

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.

dsyer avatar May 22 '17 13:05 dsyer

hybrid mode is ok for me. :)

linux-china avatar May 23 '17 00:05 linux-china

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>

linux-china avatar Jun 15 '17 04:06 linux-china

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.

dsyer avatar Jun 15 '17 05:06 dsyer

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.

joshlong avatar Aug 19 '17 08:08 joshlong

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?

blaluc avatar Apr 16 '18 10:04 blaluc

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

dsyer avatar Apr 16 '18 11:04 dsyer

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.

blaluc avatar Apr 16 '18 11:04 blaluc

I would also be interested in hybrid mode.

horschi avatar Mar 08 '19 17:03 horschi

Do you plan to update?

huyangcheng avatar Mar 31 '22 08:03 huyangcheng

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:

  • Remove internal dependencies I want to bundle by using regex replace in the generated thin.properties
  • Add the internal dependencies to a separate zip
  • Expand the zip upon deploy next to the bootable jar.
  • Add the dependencies to the classpath using the thin.libs option.

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?

werner77 avatar Oct 31 '23 05:10 werner77

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.

dsyer avatar Oct 31 '23 06:10 dsyer

@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 avatar Oct 31 '23 15:10 werner77

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 avatar Oct 31 '23 15:10 werner77

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

werner77 avatar Nov 01 '23 17:11 werner77