Writing a JSF based spring boot app so that it can also run on a Java EE app server without change - spring-boot

Spring boot is great - we have an app that runs standalone fine, using JAXRS 2, JSF 2.1.6. They versions are irrelevant really, other than they are under our control.
Our corporate deployments are on fully blown Java EE app servers though, so we don't have the option of deploying the app to something simple such as Tomcat or even as a jar with embedded Tomcat.
Trying to get a Spring boot app to work on these ends up being a world of pain, as the Java EE app server will either stop you completely or partially from using different versions of jars to the ones it ships with.
So my question is, is there a magic bullet that allows Spring boot apps to fully blown app servers like WildFly,Glassfish etc. Or what are the general approaches to getting around this issue?
The only one I can think of is to code the application to exactly the same spec as the app server, and then use Maven profiles to ship the jars for the embedded up, but to have them as provided when using them in an app server. Of course this immediately takes away the advantage of Spring not being tied down to a particular version of Java EE.

Related

Does every spring boot application create a tomcat container to be able to run?

For example,
I understand adding specific dependencies like spring-boot-starter-web that contains tomcat as transitive dependency triggers the spring framework to initialize tomcat container but I want to know if we say a spring-boot application is running, does it imply always that tomcat is also running?
I want to know if we say a spring-boot application is running, does it imply always that tomcat is also running?
No, it doesn't.
Spring boot can be used for both web applications and non-web applications.
For web applications you can use tomcat/jetty/undertow/netty for example, its up to you to chose what works for you the best.
If you don't want to run an embedded version of the web server you can opt for creating a WAR file and place it into the web server prepared in-advance.
If you don't want to run web application at all (something that is built around "Request - Response" way of work in the most broad sense) - you can create a "CommandLineRunner" - in this case you don't need to depend on neither web-mvc nor webflux. For more information about Command Line Runners read here for example
You can have an embedded server in your JAR that is able to be run on its own. By default it is Tomcat but you can change this to others, like Jetty. Additional details:
https://docs.spring.io/spring-boot/docs/2.0.6.RELEASE/reference/html/howto-embedded-web-servers.html
If you don't want to have an embedded server and you want to deploy your application you can also create WAR files instead of JAR files. Additional details:
https://www.baeldung.com/spring-boot-no-web-server
https://spring.io/guides/gs/convert-jar-to-war/

Spring Boot REST Deployment: do we need TomCat?

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.

Does spring boot needs a WAS (Websphere Application Server)?

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 :).

Deploying a third party war in a Spring Boot embedded container

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.

App Servers or Web Server for Spring Framework

first of all: that might be a newbie question. However after few searches I cannot find anything that would bring me further.
Basically what would be the reasons to choose an app server over a Spring framework to develop a medium complex web application? I am fairly new to Spring, did some hard core WebSphere for few years. While reading about Spring I see that it comes with a good bunch of features (transactions, persistence, messaging, connectors etc). Is Spring hard to scale or manage in a clustered environment?
Any comments welcome.
Thanks
Spring is awesome.
Your terminology is way off though. Spring is a Framework. It's a library that you use to write a web application.
An app Server is what your application runs in. You need both. For example, use the Spring Framework to create an app that runs in the Tomcat app server.
EAR files aren't a requirement for doing Java EE development.
It's not either/or: if you deploy a Java EE application you need a container of some kind.
I've deployed Spring apps on Tomcat and WebLogic. I think WebLogic is the best Java EE app server on the market. My decision about whether to deploy to it or not would be based strictly on availability.
You've seen that Spring has their own Java EE container now. It forks Tomcat and marries it with OSGi and Spring. I haven't tried it yet, but if the quality is similar to their framework it will be very promising indeed.
Are you really asking "When would I write an application using Spring? When should I choose EJB3?"
My preference these days is Spring. I can do persistence, transactions, messaging, web services, and everything else I need.
Bpapa,
you got me there, yes the terminology is wrong. I meant Spring + web container vs. App Servers. Surely the web app has to be deployed somewhere. I guess that shifts the question to the server side features as per my first post.
Topology example: Spring + Tomcat vs. WebSphere.
As a side note: people argue if Tomcat is an app server, many consider it rather a web container. You could not deploy an EAR file to Tomcat, can you? All it takes is a WAR, am I right? But that gets too academic.
Thanks a lot
Rod Johnson's "Expert 1:1 Java EE Development Without EJBs" is the basis for Spring. It's an excellent book, but I'd say it's a bit out of date now. The book was written with EJB2 in mind. It was published before Spring became an open source project. The framework is up to version 3.0 now, so I'd say that the book is of historical interest only. I'd recommend a more modern take on the question that takes Spring 3.0 and EJB3 into account.
%

Resources