I am new to Spring MVC and I have now come accross tutorials that explain how to deploy your web project as a .jar. My IDE is the Spring Tool Suite. I have always used .war + Apache Tomcat.
Can someone elaborate a bit from the practical point of view why to use .jar instead of .war? Any problems to be aware of?
edit: other answers are welcome too
Spring Boot uses fat JAR packaging where is embeds Servlet container with all dependencies into this single JAR.
If you are using Maven, it uses spring-boot-maven-plugin to package the project.
Practical usage of this approach is simple. Ability to easily run Srvlet based Spring application from command line with externalized properties. Such configuration enables powerfully orchestration possibilities which are often used in modern enterprises in so called Microservices or SOA architecture.
There is group of people out there (including myself) which believe that deploying various WAR files of unrelated applications into single Servlet runtime is not very good idea.
So fat JARs are handy for separate Servlet runtime per application deployment.
About having .jar and Tomcat + .war on the same machine, it is possible and I use this. This may be not cool but I had a .war application running in a tomcat server before the rise up of spring boot. Now my new apps are spring boot apps, and we are migrating our architecture to SOA concept, but we can't change the tire with the moving car. The main application, the WAR is running in a tomcat server and the others (.jar) are self contained ( embedded tomcat ), each one running in a different port. It was the most viable solution available for us by the moment.
Related
I've seen Spring Boot Rest project that generates WAR then deployed in a tomcat container. I wonder if this is best practice because I've also read that in Spring Boot, the new final executable JAR file contains embedded server solution like Tomcat too?
Now i've seen a related post that talks about Spring Boot supports both ways but none talked about the pros and cons of each.
Can someone point out the best practice for deploying a spring boot rest project?
I'm thinking of dockerizing the JAR containing embedded server but i'm wondering if there's any drawbacks vs deploying WAR to Tomcat?
A general best practice ( from 12 Factor App ) regarding the application environment and dependencies is "Explicitly declare and isolate dependencies".
A twelve-factor app never relies on implicit existence of system-wide
packages
With that in mind one should gravitate more towards using embedded container as part of explicit dependency instead of a requirement that needs to be fulfilled separately.There are multiple choices for embedded container in the jar artifact (like tomcat, jetty, undertow, netty) and their respective configuration is also extensive, so using these in production environment is recommended ( I have used them a lot). However there might be certain times when you would want to create a war instead, for e.g., a war file will be deployable in any full-fledged EE Application server ( Weblogic, Wildfly etc) which might be mandated by your environment. With a war, your number of options in terms of app server increases. Personally for me, spring boot jar with embedded tomcat has been quite effective. With embedded container option what you need is a virtual machine with OS and Java installed and you are good to go.
However there is a special limitation related to JSP as mentioned here in Spring Boot documentaion which explain a good reason why you might need to package as a war but still run as jar.
I have an interesting decision to take for my project.
We use spring boot for our micro services.
The development environment is spring boot wíth tomcat in the embedded mode.
However, I am not sure if there are any advantages/ drawbacks if I choose this way in production too.
The counter argument is to deploy a war in a separate tomcat.
I am not able to think on any buying points for both views
What will be the best choice for a large enterprise production system on cloud(jar/war)?
I saw some recommendations here (but I need more stronger reasons to chosse/ not choose any one): Spring boot embedded container or war file in an external container for production
here are my points to use fat jar for production deployment.
fat jars are simple to build and deploy.
Spring Boot aims to be production ready, by default. This means that
it ships with useful defaults out of the box that may be
overriden, if necessary.
Fat JARs are good for running as the microservices as managing
microservices is already a burden then why one more step to
configure and deployment should be considered.
fat jar can also run as a java service easy to manage by a single command, restart server/jvm can be managed automatically.
Spring boot is Embedded with- Tomcat, Jetty and Undertow so changing
app server for any micro services is not a big deal.
In my theory spring boot is capable of running java web application stand-alone. It says it has a own embedded servlet container and can use JNDI itself.
I built a war file before (spring-mvc, security, gradle built), but Spring boot assemble jar file and it runs on any machine which has JVM.
So my question is, if I made a spring boot based web app (contained JSP files & JNDI for looking up datasource), although it has own embedded servlet container and packaged jar file for running standalone, do I still need to package it as WAR file and deploy it in WAS (Websphere Application Server) or servlet containers for any reasons such as performance, stability, scaling-out etc?
WAS is an full blown Java Enterprise Application Server, on the other hand you have Spring that only requires a Servlet Container (Servlets are a part of full JEE).
Servlet Containers are for example: Tomcat, Jetty, but also WAS.
Spring Boot is able to package the complete application TOGETHER with the code of Tomcat in an JAR, so that this jar contains the Servlet Container and your Application.
Do I need a additional WAS for performance, stability, scaling-out etc?
Performance: No - There should be no important performance differerence between Tomcat and WAS when you run a Spring-Application. (Only that Tomcat needs less memory for itsself)
Stability: Tomcat and WAS are both very mature products.
Scaling: You can build a cluster of Tomcats by your own.
The main features of WAS over Tomcat are:
- WAS supports EJB and CDI (Tomcat would need TomEE for this), but Spring will not use it, because it is its one Dependency Injection container
- WAS has more Monitoring features, but this does not matter, because Spring Boot has Actuator
#See Difference between an application server and a servlet container? for more details
Simple answer is No. You do not need any Full blown application servers for any of the reasons that you mentioned (for performance, stability, scaling-out). You can just do fine with tomcat
Edit
Looks like you are using only JNDI feature from the Application server. Do you really need JNDI when you pack your servlet container along with your application ? I don't think so. That days are long gone.
JNDI really shines when you have to move an application between
environments: development to integration to test to production. If you
configure each app server to use the same JNDI name, you can have
different databases in each environment and not have to change your
code. You just pick up the WAR file and drop it in the new
environment.https://stackoverflow.com/a/7760768/6785908
(If you still need JNDI to be used to look up your data source refer: https://stackoverflow.com/a/24944671/6785908).
No, still I do not really see a reason for packaging your application as WAR and deploy it to traditional application server. That being said, if you have some existing infrastructure lying around and you are being forced to deploy to existing WAS (or WebLogic or JBoss any application server for that matter) server, then I rest my case :).
Currently I'm deploying multiple war files into a Tomcat container. Is it possible to use Spring Boot to put all war files into a single deployable jar? I know this is possible for a single app, but can it be done to deploy multiple apps that once were in separate war files?
Spring Boot by design will run one app (one war) per container. If you want to go for the uber-jar deployment I suggest you stay with this since it is following also 12-factor-app best practices.
If you want to run multiple war files in one tomcat I suggest you follow the "old way" wrapping up your spring boot apps in war files and deploy them in an already set up tomcat or jetty or ...
So the answer will be: in principle – and with a lot of tweaking – you might be able to achieve what you are trying to do but this is not the intend of the jar distribution of spring boot apps. And always remember: work with the framework and not against it.
Tomcat container browses through the web apps and maps each war with the context root defined in it (single property of the web.xml). So, i do not think you can do merge the files in only one and still treat them as separate web apps.
What can be done is to actually merge the code of the web apps in only war file and split the functionality based on different paths after the context root path.
Pardon if this feels a bit of "necroposting". I looked and found only one similar question with no answers here (Spring-Boot Embedded Wars).
I have a service packaged into a spring boot (1.0) container. This service uses activiti (www.activiti.org) to manage some buisiness processes. I am trying to deploy inside the same spring boot container, the war for activiti-explorer. This war has its own web.inf, spring config, et cetera, so it may conflict with the existing spring config, but nonetheless, I'd like to try to deploy that war as it is.
I haven't found any way to do that, and suspect that spring boot doesn't support the deployment of pre-package wars into the embedded container, isn't it?
Just as a warning, I think I can't put the extracted war into the spring-boot jar as I feel it needs a fully functional web container. If spring-boot doesn't offer this functionality, no big deal, we're going to deploy that war on its own tomcat, but it would be handy if it could be.
Thanks
Update
Just to clear better, I have an already running Spring Application standalone server, with its own embedded Tomcat.
Inside the embedded Tomcat I plugged some #Controllers I developed.
Then I was also able to map a third-party servlet using a ServletRegistrationBean (mapped to /servlet-path).
Now I'd like to do something similar with another war that contains a full fledged web application (it's a vaadin/spring 3.2 application with its own libraries, jsps, static resources ...) and would like to map it to (say) /war-path.
I would like to drop the war in a well known location and deploy it into tomcar with a (say) WarRegistrationBean that would let Tomcat handle all the classloading hurdles (as I mentioned, the war is using spring 3.2 while I'm using 4.0 with spring boot, ...).
I suspect that this last feature is not supported by spring-boot or - possibly - even out of scope for the project itself.
You can manually enhance a war archive by adding the stuff that the boot plugin does (classes from the loader and some META-INF information). Easiest would be to simply enhance an "empty" war, and then merge it with the target one (by exploding them both and re-jarring). The only thing you'd need to add might be a main class.
It's still a gap in the Boot tooling. If you think it needs filling please raise an issue and/or send some code.