Replace old Spring Boot Jar with new one - spring-boot

I'm running a spring boot executable jar as a service under Linux and it works fine.
My question is, there is a way to replace the running jar with new jar without stopping and rerunning the service?
Thanks,
Avi

In a nutshell, it is impossible to reload spring-boot jar in production environment.
I guess your final goal is to "hotswap" your application without user notified. Thanks to service discovery, you can do this by:
Start your new application and keep the old ones running.
After the new one started and registered in service discovery server, shutdown the old ones.
That's how we do upgrade of our services, and Docker saves us a lot of time.

Related

Can you replace a Spring Boot jar while the application is running?

In our Linux environment applications are restarted periodically (the reasons aren't important here). It would be convenient for us to deploy new versions of an application by copying the application Spring Boot jar on top of the existing (old) jar thereby overwriting it and then simply wait for the application to restart (that is, the JVM running the application to restart).
However, this seems to not work. We get different kinds of errors - sometimes the app just hangs, sometimes we get a ClassNotFoundException. It's as if Spring Boot (or something inside Spring Boot) reopens the jar and expects it to be the same one it was when the application was originally started.
We had a look through Spring's common application properties, but didn't see anything appropriate. Is there a way to make this work? When we were using WAR files we configured the servlet container to unpack the WAR file and run from the unpacked version. Can we do something similar with Spring Boot?
First of all the errors you are experiencing can come from multiple sources. Usually replacing the file from a process is not a big problem as the whole file is loaded into memory before execution. Java is a little bit different, because the actual process that is running is the JVM and it only loads the jar file from disk. The JVM loads classes only on demand, this means if there was any class that was not loaded before it will try to load it and most likely fail, if the jar file is different. In the case of spring boot there are also other resources (such as HTML files) inside the jar file that are dynamically loaded.
You mentioned you are using a linux environment. If you can just replace your startup with a script you can just copy the jar and start it from the copied location:
#!/bin/bash
JAR_NAME="spring-boot.jar"
NEW_JAR_NAME=".$JAR_NAME" # Use an appropriate name here
cp $JAR_NAME $NEW_JAR_NAME
java -jar $NEW_JAR_NAME
rm $NEW_JAR_NAME
Now every time you start the application a copy is being made and started from there. You can replace the original jar and on the next restart the new application will load.
You coud also use rsync instead of cp to avoid copying the same jar twice, if the application is restarted multiple times without changing the jar.
It would be convenient for us to deploy new versions of an application
by copying the Spring Boot jar on top of the existing (old) jar and
then simply wait for the application to restart
Why would you do such a thing to yourself? You are trying solve a usecase that's against best practices, sound like asking for trouble just to avoid an app restart. When you are doing a deployment, you need to make sure the deployment went through, otherwise how will you troubleshoot if something goes wrong in your application, you will have one more variable in hand when you troubleshoot, i,e the uncertainty of current version of the code.
If you are having downtime while deploying (I am assuming thats why you want to limit the restarts), why don't you bring up another instance with the newer version of code and once its healthy shutdown the old one

how replace Spring Batch Admin by Spring Boot Admin

My straight question is: in Spring Batch Admin there is a clear concept and practical functionalities to manage the jobs. So, in Spring Batch Admin you can launch, stop one job, stop all jobs, reatart, abandon, see the status for each job and check if it was successful or failed. In case I use Spring Cloud Task deployed as war and Spring Boot Admin deployed as war in same server, how can I manage my jobs?
Explaining better my context: I have developed few Spring Batch jobs in the last 6 months. All them were designed in order to run periodically, in other words, to be schedulled. I wasn't planned deploy them in Web Server but I was informed in my company in the moment to publish to production that I must run any solution inside of our Mainframe Websphere.
It wasn't any issue at all since I realized that I could use Spring Batch Admin in order to start/stop all the Spring Batch deployed in the same EAR. Unfortunately, Websphere ND 8.5 isn't comply with Spring Batch Admin (you may heard someone telling he/she has managed to make Spring Batch Admin up and running in Websphere 8.5 ND but I got the final position from IBM that neither JSR352 nor Spring Batch Admin is safe to be used).
One week ago, I firstly got in touch with Spring Boot Admin thanks to certain comment to my question how to register org.springframework.integration.monitor.IntegrationMBeanExporter.
In such comment I read "...consider to get rid of batch-admin. This project is obsolete already in favor of cloud.spring.io/spring-cloud-task..." however it doesn't seem to me to really provide the same functionalities Spring Batch Admin does. It seems to me be a bit more generic and aimed for application boxes instead of job executions.
To make my question even more clear, let's say I have this project deployed as war https://github.com/spring-cloud/spring-cloud-task/blob/master/spring-cloud-task-samples/batch-job/src/main/java/io/spring/configuration/JobConfiguration.java and the two jobs are both schedulled for run every 5 minutes. Addtionally, in such project I added the necessary configuration to make it visible to Spring Boot Admin (e.g spring-boot-admin-starter-client). In the same server I have this Spring Boot Admin deployed as war too https://github.com/codecentric/spring-boot-admin/tree/master/spring-boot-admin-samples/spring-boot-admin-sample-war. Now, my question that is the same from title but a bit more exemplified is: will I be able to stop one job and let the other keep running from Spring Boot Admin? Can I launch one and leave other stopped?
If you, reader, has an overview of Spring Batch Admin will probably understand quickly what is my intention. I read in th Spring Boot Admin manual
http://codecentric.github.io/spring-boot-admin/1.4.1/#jmx-bean-management
3.2. JMX-bean management "... To interact with JMX-beans in the admin UI you have to include Jolokia in your application". Is there some trick via Jolokia in order to manage each job individually?

Tomcat stop after failed deployment?

I would like to stop Tomcat when a war deployment fails. Is there some hook or listener which could be used for that?
I know, normally one would not make the container stop when a deployment fails. In my case I would like to implement a Fail-fast error model with Tomcat since there is currently no chance to replace the WAR with a fat jar with an embedded Servlet engine (e.g., Spring-Boot).
In the mean time I have implemented a Tomcat LifecycleListener which shuts down TC when a deployment fails: https://github.com/ascheman/tomcat-lifecyclelistener
Thanks to Thomas Meyer who gave some hints on Twitter: https://twitter.com/thomasmey/status/752971635825729537.
Spring boot provides shutdown hook. SOF has similar query as below
Spring Boot shutdown hook
This can give and idea to implement your app Fail Fast behavior with hook.

Jboss deploying a ear and war file in the same server instance

Is it possible in Jboss deploying a ear and war file in the same server instance? If so any good source to get started? Any suggestion.
I have two applications deployed under my default deploy folder of jboss. I am running one application from which i have to call the other application to get some data. Is this possible? If so how to get started??
It is actually recommended that you only put 1 application in a server instance as a time. That said, I have had multiple ears and wars running in the same instance while I am developing. But for production it is better to separate them out. Since there is no extra cost involved this makes it easier to observe and debug apps.
Do you have a specific reason for wanting them to run side by side?
What version of JBoss are you running.

Tomcat Hot Deploy to instance hosting several applications

My question is about deployment to a Tomcat server instance which hosts multiple applications and hosts application contexts for Struts, Spring, and Hibernate. I would like to deploy changes to one application without restarting my Tomcat server.
As an example, many times in our firm we have to deploy new applications or versions of applications to our tomcat enviroment and the process could be:
Move class and jsp to the exploded folder then the context reload itself, or
Another scenario is when we have to deploy new features which require
modifications to xml contexts such as struts-config.xml or spring-application-context.xml.
Currently we have to restart the web-server to load new configuration. This would be OK if Tomcat did not have other live applications which we did not want to interrupt and restart. As an example, if I have an application which uses hibernate and struts, then I have to re-deploy it to a Tomcat server with many other applications running, and I deploy the new application and restart the server. This is not ideal.
So the question is when deploying changes to Tomcat, including context changes, do I have to restart? Is there a way to do a hot deploy for only this specific application and maybe re-start only its context without restarting the webserver?
Thanks a lot!!
Best regards
You can set the "autoDeploy" attribute to "true" in server.xml. You can read more detailed information here http://www.mulesoft.com/tomcat-deploy.
Hope this helps.

Resources