Spring-boot: Document how to use BOOT-INF in spring-boot executable jar as a library jar with Gradle

Created on 2 Sep 2016  路  3Comments  路  Source: spring-projects/spring-boot

I recently tried upgrading the spring-boot-gradle-plugin from version 1.3.1.RELEASE to 1.4.0.RELEASE and encountered a compilation error in my projects as a result. After investigating it appears that the root of the issue is that when using spring-boot to create executable jars that are intended to also be used as executable jars the addition of putting classes from the project into the BOOT-INF directory within the jar prevents those executable jars from also being used as a library jar.

As an example scenario:

I have two projects A and B. They both need to be executable jars, however project B relies on some classes in project A. In spring boot version 1.3.1.RELEASE this is fine because all of the programs classes are kept in the root of the jar file. In version 1.4.0.RELEASE of the spring-boot-gradle-plugin, however, all of the classes are kept in a BOOT-INF folder inside of the jar file which hides those classes from anything that would add that jar to it's classpath, causing compilation errors such as 'symbol not found'.

So it appears that in spring-boot-gradle-plugin 1.4.0.RELEASE you lose the (perhaps unintended) functionality of being able to use a spring-boot generated executable jar as both an executable jar and a library jar. Whether this is actually considered a bug or not I'm not sure.

For reference: https://discuss.gradle.org/t/when-updating-to-spring-boot-gradle-plugin-1-4-0-release-lib-project-dependendency-isnt-in-classpath/19325

documentation

Most helpful comment

Conceptually, it's no different to Maven. You just need to set a classifier on the boot repackage task. The description of the classifier property already hints at the need to set it:

A file name segment (before the extension) to add to the archive, so that the original is preserved in its original location. Defaults to null in which case the archive is repackaged in place. The default is convenient for many purposes, but if you want to use the original jar as a dependency in another project, it鈥檚 best to use an extension to define the executable archive.

We should strengthen the language a bit as you should always set the classifier if you want to use a Spring Boot app as a dependency.

All 3 comments

We wanted to bring the fat jar packaging closer to the way that classic WAR files are structured and this has unfortunately means that your 1.3.x based code will need some changes.

A similar issue was recently raised by someone using Maven and you can see the suggested fix here. Our resident Gradle expert is taking some well earned vacation at the moment, but hopefully that Maven solution is enough to give you some ideas.

I'll change this issue to documentation one and we'll try to come up with an equivalent Gradle sample when he's back.

Conceptually, it's no different to Maven. You just need to set a classifier on the boot repackage task. The description of the classifier property already hints at the need to set it:

A file name segment (before the extension) to add to the archive, so that the original is preserved in its original location. Defaults to null in which case the archive is repackaged in place. The default is convenient for many purposes, but if you want to use the original jar as a dependency in another project, it鈥檚 best to use an extension to define the executable archive.

We should strengthen the language a bit as you should always set the classifier if you want to use a Spring Boot app as a dependency.

Maybe we could harmonize with what was done for Maven?

Was this page helpful?
0 / 5 - 0 ratings