Spring Boot Maven plugin: What does it actually do? - spring-boot

Can someone give me an understanding of what the Spring Boot Maven plugin actually does? I have been Googling, but most of what I find doesn't give a clear picture.
The impression I have so far is that it can create a "fully executable" jar that does not need to be run via java -jar, and that it's also possible to make a more traditional jar that you would run via java -jar. I'm sure there are other variations of what it can produce as well.
I'm also under the impression that it can package up dependencies and resources. It's not at all clear to me how the resources are "accessed" by the application when it's run.
In either of the outcomes described above do I need just the jar and nothing else (i.e. no resource files, dependency jars, etc.)? In other words, is the jar self-contained? When I've opened the jar up, it does seem that everything it needs is there. Is that really the case?
Now, let's go a little further towards what I'm trying to do. I am writing a set of Spring services with REST APIs. Each service will be run in its own VM (or container - future). The services are packaged into a single jar and the service to be used is selected via Spring profile (i.e. spring.profiles.active=a-profile).
The way I've done things like this before has been to use the Maven assembly plugin to produce an archive (zip) for each separate service and inlcude all of the necessities (dependency jars, resource files, etc.). I'd place it where needed, unpack it, tweak some configuration and run it via an included script.
I'm getting the impression that's not "how it's done" when the Spring Boot Maven plugin is involved.

The Spring Boot Maven Plugin provides Spring Boot support in Maven, letting you package executable jar or war archives and run an application “in-place”.
It builds the uber jar which bundles in Tomcat along with your app. If you inspect the contents of the jar with jar -tf <file_name> you will see that the format is a bit different. The Spring Boot classes look normal, but then your project's files are inside a BOOT-INF folder.

Related

How to bundle war file containing rest code with jax-rs dependencies so that it runs on Tomcat?

I'm using a Gradle based-setup to build a REST web service (with Jax-Rs and glassfish.jersey dependencies). I'm using the Gradle-tomcat plugin (bmuschko-gradle-tomcat-plugin) to deploy it on tomcat during runtime. I'm pretty new to this, and I've read that tomcat doesn't support Jax-Rs features on its own. So how do I make my REST code work on tomcat? Should I bundle Jax-rs/jersey jars along with my war? I won't be able to copy-paste those jars anywhere (few tutorials have the jars pasted under web-inf/libs module), I want it to be automated during the build with Gradle.
PS: I'm using #ApplicationPath (mandated by my company) in my code, which overrides servlet-mapping in the web.xml, so I won't be able to modify that.

Is it possible to make one fat jar with two spring boot app inside each with #SpringBootApplication main

I'm totally new to spring boot/gradle, so if i say something wrong, please feel free to correct me.
I have two spring boot projects and i'm using Spring Boot Gradle Plugin to run one by one in different ports and to also generate the respective jars.
I want to know if it's possible to generate one fat jar that can run both projects in different ports.
Here's the structure of my project:
Project
setting.gradle
Project-1
src/.../#SpringBootApplication Main
build.gradle
Project-2
src/.../#SpringBootApplication Main2
build.gradle
I included both projects in the setting.gradle, the Project-2 in the dependencies of Project-1 and tried gradle clean build, but the fat jar generated in the Project-1 doesn't include the Project-2's jar. What I expected is that when I run the fat jar it exposes the two projects in their respective ports, as if I did gradle bootRun on each project.
Is what i'm doing correct? I'm assuming that putting the Project-2 in the dependencies of Project-1 would make gradle create the fat jar I want.
Or that's not possible and I just need to use the two jars that are given to me?
Thank you for your time.
You can deploy two separate jars behind the same tomcat instance to get the same outcome. Say if you deploy my-first-jar.jar and my-second-jar.jar behind tomcat, you will get two set of endpoints like:
http://localhost:8080/my-first-jar/apis-from-first-jar
http://localhost:8080/my-second-jar/apis-from-second-jar
However, seems like what you are unable to create a fat jar correctly. By default the dependencies of the project are not included in the jar. You need to explicitly say to the build tool(gradle, in your case) to make a fat jar. Have a look here
Once fat jar of Project 1 is created, it will have files from project 2 as well, but you would be able to run only single spring boot app.
PS: You can run multiple apps my combining in a single container application if u wish. Have a look here but wont recommend you to go down that road coz its messy

Making a spring boot fat jar file with gradle WITHOUT a spring boot gradle plug-in (no access to bootJar)

I have a spring-boot application in which I loaded all the necessary (or so I believe) dependencies to run without using spring-boot initializer or the spring-boot gradle plug-in. These tools are not available for me at my work. I can run the application through intellij without issues, but when attempting to run a fat jar, I am met with
No auto configuration classes found in META-INF/spring.factories.
Now the spring.factory files ARE located inside the fat jar (there are multiples of them) and they are inside the meta-inf directory.
Spring boot has so much automated functionality, I am not sure where to begin. There are a lot of similar posts and everyone just tells people to use the spring-boot gradle plugin bootJar task but as I said these are not available to me. I need to get it running without those tools,
if anyone has insight into what the issue may be or how to resolve it, any help is appreciated. I will try to add more details later.
I am using spring-boot v. 2.1.1 and spring 5.1.4

Unable to load Spring Framework Libraries in Wildfly accessible to deployed JAR

I am writing a custom Keycloak User Storage SPI, which is JAR file. I would like to use Spring DI in the JAR. I have added Spring JARs as Modules in Keycloak's Wildfly server.
Also, not able to load Spring context as Keycloak User Storage SPI initiate from META-INF.services "org.keycloak.storage.UserStorageProviderFactory" and invokes UserStorageProviderFactory.init method.
It also doesn't read the properties file inside resources directory.
Please advise how can I make this work.
May be, there would be workaround by using .ear file with your jar wrapped into it. If you are using maven then you can reside all required spring dependencies in that pom of your jar.
For further reference, you can go to this git link which might be related to what you are doing.
https://github.com/thomasdarimont/keycloak-user-storage-provider-demo

Spring Boot Migration Issue on Packaging JAR and WAR using Maven

We are trying to migrate our existing Spring MVC applications to Spring Boot application. Our existing applications are using 3.2.9, so tons of XML configurations. All the beans are defined in the XML files. What we have done is first we have upgraded our existing applications to Spring 4.2.5 version since Spring Boot will work only with Spring 4 versions.
Our requirement is to have both FAT JARs and WAR files from the build. Most of our existing customers would prefer Application Server deployment, so we have to create WAR file for them. Also for our internal testing and new deployments, we are planning to use FAT JARs.
How can we achieve them in the Maven file, we are able to provide separately as below. Is there any maven plug-in to generate both in single build?
<packaging>jar</packaging>
or
<packaging>war</packaging>
We are publishing our artifacts into Nexus repository. So, we want to have the separate repository location for JAR files and WAR files. Can we do that using the single pom.xml file?
Also another question, we have all the XML configurations under WEB-INF folder. When we are moving to the Spring Boot application, it has to be under the resources folder. How can we handle them easily. When we build FAT jars, the resources are not looked under WEB-INF because it simply ignores the webapp project.
I am looking forward for some guidance to complete the migration. Infact, we have already done that changes and it is working fine, but we are confused on this WAR / JAR generations.
Update:
I have got another question in mind, if we are converting our existing applications to spring boot, do we still have to maintain WEB-INF folder in the web-app or can move everything to the resources folder?. While building the WAR file, whether spring boot takes care of moving the resources to WEB-INF? How spring boot would manage to create the WAR file if you are putting all the resources under the resources folder.
Building WAR and FAT JAR is very easy with Gradle.
With Maven, I would try multi module setup, where one sub-module will build fat JAR and second will build WAR file.
Application logic can be as third sub-module and thus being standalone JAR with Spring configuration and beans. This application logic JAR would be as dependency for fat JAR and WAR module.
WAR specific configuration can be placed in Maven WAR sub-module.
I didn't have such requirement before, so don't know what challenges may occur. For sure I wouldn't try to integrate maven-assembly-plugin or other packaging plugins with spring-boot-maven-plugin.
Concerning location of config files, just place them into src/main/resources or it's sub-folders according Spring Boot conventions. Spring Boot is opinionated framework and will be most friendly to you if you don't try to resist defaults.
Maven does not handle this gracefully, but its far from difficult to solve. You can do this with 3 pom files. One parent pom that contains the majority of the configuration, and one each for the packaging portion of the work. This would neatly separate the concerns of the two different assembly patterns too.
To clarify -- I'm not recommending a multi-module configuration here, just multiple poms with names like war-pom.xml and fat-jar-pom.xml, along with parent-pom.xml.

Resources