Spring Boot (Reactive) - bootJar vs Service Provider Interface (SPI)

403 views Asked by At

I'm using Reactive Spring Boot with Netty and Gradle as a build system. To build production's executable I use a task bootJar with launchScript().

I'm also using various TwelveMonkeys' plugins for ImageIO processing. Everything works fine when I run the application from IntelliJ but when I build it with bootJar - those plugins are not working - just like they were not installed.

I opened the jar produced by Spring, and all plugins jars are inside.

On the TwelveMonkeys' manual, they say:

The recommended way to use the plugins, is just to include the JARs as-is in your project, through a Maven dependency or similar. Re-packaging is not necessary to use the library, and not recommended.

However, if you like to create a "fat" JAR, or otherwise like to re-package the JARs for some reason, it's important to remember that automatic discovery of the plugins by ImageIO depends on the Service Provider Interface (SPI) mechanism. In short, each JAR contains a special folder, named META-INF/services containing one or more files, typically javax.imageio.spi.ImageReaderSpi and javax.imageio.spi.ImageWriterSpi. These files exist with the same name in every JAR, so if you simply unpack everything to a single folder or create a JAR, files will be overwritten and behavior be unspecified (most likely you will end up with a single plugin being installed).

So here's a couple of questions:

  1. Does the bootJar task create a fatJar or is this something else?
  2. Is the jar, created by bootJar, capable of discovering the plugins using SPI, as described in above comment?
  3. If it's capable of doing that - why it's not working and what are possible places to start investigating? (perhaps is this configuration problem?)
  4. If it's not capable - is the shadowJar the only solution to that problem?
0

There are 0 answers