SpringBoot war and JNDI DataSource standalone not working - spring-boot

I have a SpringBoot2-Application configured as a war package that I want to run on the command-line but also be deployable in an application server.
Per the instructions, I configured the dependency to the embedded Tomcat to scope "provided" and also added a TomcatServletWebServerFactory to override the initialization of the embedded Tomcat so that I can enable jndi.naming because I want the datasource to be read from the jndi of the application server. In case I start the application standalone, I provide the jndi-resource by adding it to the embedded Tomcat during start.
This fails nicely: if the scope is "provided" and starting standalone, my TomcatServletWebServerFactory is not run and jndi is not activated so the lookup of the datasource fails. But that package works fine in Wildfly. If I remove "provided", the standalone application starts fine but it crashes in Wildfly out of obvious reasons (there is a Tomcat instance started to many that can not be cast to an Undertow-instance).
Has anybody else experienced this and has a solution? What does the SpringBoot-Maven plugin do to "hide" an embedded Tomcat in a war? Maybe my TomcatServletWebServerFactory has to adjust to the "provided"(hidden) configuration?
Thanks for all suggestions.

Related

Where to install JDBC driver for Vaadin app run from IntelliJ using bundled Jetty servlet container?

I will ultimately be deploying my Vaadin web app to Tomcat servlet container.
In Tomcat, JDBC drivers generally need to be stored outside of the web app, in a separate Tomcat folder. So I do not want to add any JDBC driver as a dependency within my Maven build settings.
In the meantime, while developing I am running the Vaadin 8 or 8.1 web app (created from the vaadin-archetype-application Maven archetype) from within IntelliJ 2017.1 using the Jetty servlet container that is somewhere mysteriously bundled (“embedded”?) within the project.
Where can I store my JDBC driver jar file(s) while developing with IntelliJ-Jetty combo?
This depends on wether you use Tomcat or Jetty as an "old fashioned" appserver, or if you use it as an embedded component in your application. The archetype you have used probably assumes the latter (adds jetty-plugin to pom), while it sounds like you want the first scenario. In that case, just install the driver in the tomcat or jetty instance you want to use, and create a run configuration in IntelliJ for that instance. If you need the driver compile-time, add it to the pom with scope "provided". If you want to just have it available to the jetty-plugin, add it as a dependency for that plugin (inside the plugin definition).
See this related question for more info about including dependencies only for embedded jetty.

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

How spring starts embedded tomcat

Normally, when you developing a simple mvc application, with maven, based on Spring Boot, you starts from SpringApplication.run(.class, args), then endpoint that returns you e.g. "Hello World". After that you write mvn spring-boot:run (or start it by your ide) and Spring makes everything for you.
Spring also setting up Tomcat servlet container, and then deploy your package to that, so you don't need to make it manually.
And my question:
How exactly Spring starts that Tomcat service? If i would like to start in same way some other services e.g. Apache Felix, Apache Jackrabbit or some other, what should I do? Is that any configured bean that is set in starter package, or some other mechanism?

Spring Autoconfiguration Issues with Tomcat vs. Jetty

I am creating an application with websockets where I use Spring's autoconfiguration ability via the #EnableAutoConfiguration annotation before my main class. I am attempting to use Tomcat because that is what I am familiar with. I am using apache camel to route my messages and the camel dependencies have a lot of jetty jars in them.
The jetty jars are forcing the autoconfiguration in spring to start a jetty instance rather than a tomcat one and I was wondering if there was any way to add parameters or anything else to the autoconfiguration annotation that would ensure it worked how I needed and started the Tomcat instance regardless of the jars in my dependencies. I tried excluding all of the jetty jars, but it still wouldn't revert to Tomcat like it was before I added the back end camel to my application.
Any advice? Thanks in advance for the assistance.

EJB3 initialization code

I've searched this for a while now, but can't seem to find an answer to this. How can I execute some code in when deploying an EJB3 jar-file to a JBoss server? For example, I need to run some sql migration scripts before the beans are ready to be used.
If you can't use EJB 3.1 (with #Singleton #Startup), I would recommend packaging your EJB module in an EAR with a WAR. Add a ServletContextListener to the WAR, and take your action in the contextInitialized method.
You can create a JBoss MBean service with a Listener that can perform any initialization (SQL scripts run in your case) after JBoss is fully started and before any EJB is used.
I have created such a service and we run it on JBoss 4.2.3.GA, so, you do not need to migrate to JBoss 7.

Resources