can spring auto reload changes like grails? - spring-boot

One of the main benefits of grails, which is based on Spring, is that you dont need to rebuild and re-run the entire application (which takes minutes) each time you change a line of code, it just recopiles that one file and auto-loads the changes.
Following this tutorial:
https://spring.io/guides/gs/spring-boot/
To run the app, you have to use the command line and do this outside of intellij:
./gradlew build && java -jar build/libs/gs-spring-boot-0.1.0.jar
If you change a line of code, e.g. in a controller, you have to kill the application, rebuild it and restart it, which takes a while.
I came across something called automatic restart in dev tools. Is this something to do with auto-reloading of changes, and if so, how is it used?

If a class is changed , I am sorry that Spring boot devtools will not just reload that changed classes but it will restart the whole application automatically . But this restart should be faster than the normal cold start based on what the docs said :
The restart technology provided by Spring Boot works by using two
classloaders. Classes that do not change (for example, those from
third-party jars) are loaded into a base classloader. Classes that you
are actively developing are loaded into a restart classloader. When
the application is restarted, the restart classloader is thrown away
and a new one is created. This approach means that application
restarts are typically much faster than “cold starts”, since the base
classloader is already available and populated.
If you need to just reload the changed classes , you may consider to use JRebel which is not free.
To use spring boot devtools , just includes its dependency and then start the application as usual using IDE.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
It will the monitor the classpath folders and then restart the application if there are any changes in these folders.
In case of Eclipse , what you need is to ensure Project ➡️ Build Automatically is selected. Once the source codes are changed , Eclipse will then just compiled that changed sources codes to the classes in the classpath folders automatically which trigger devtools to restart the application.

Based on the #Ken Chan answer but very briefly
For Eclipse - click in the menu "Project" -> select "Build Automatically"
In my case I was running some spring boot server - I had to stop the server, enable "Build Automatically" like on the picture, then start the server again and on every change - the code recompiled.

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

Spring Boot fastest way to deploy instead of build Jar?

I am new to Spring Boot from php world. In Php development, it is simple to make changes on the file, upload and run.
But on Spring boot, my development relies on remote ubuntu server, every time I make change in *.java, I have to build the Fat Jar, upload the Jar, kill the current java process on ubuntu, and run the java -jar my.jar again, which spend much time on the upload because the Jar is about 60 mb.
Is there any way I can work like php, just upload the changed file, so the spring boot just compile the class and run?
Does change to build *.war help to faster deployment?
There are a few option to mitigate the roundtrip of building the jar file and upload it.
Hot-swap: For minor changes, you can hot-swap changes automatially when you have a remote-debugger attached. I use Intellij as Ide, which provide this out of the box after a file is recompiled, see more at this link how to enable it.
Reloading tool: use a tool that are designed to reload Java classes, such as JRebel which extends the classloader and updates a class if a change has been detected. However, they are often only available in a paid version.
Spring Boot dev-tools: this tool also monitors changes and restart the application with the new changes (so no need to rebuild the jar file). It is possible to use on a remote application. See this link for more info.
Using a war file is different concept since a war file is executed inside an application container (e.g a Wildfly server). You can dynamically upload a war file to a running application server, which will only restart the war file. But I'm not sure if this will lead to faster deployment, however it is a different approach how the application is run.

Flyway with spring boot overwrites whole DB every time I switch run mode between WAR and IDE run

I'm facing very weird issue while integrating flyway DB migration with spring boot application.
When I run the application from executable WAR using command line, it creates new DB at the start-up of application.
Now, If I switch the application run mode to IDE (i.e. run from STS), it again fires all the script from my db/migration folder. I can see the installed_on column time changes every-time I switch between these 2 run modes. I have tried enabling baselineOnMigrate property, but didn't get any effect of it.
Do you think its something related to spring boot embedded tomcat ? because at both run it creates individual tomcat which is embedded.
Please find my spring boot application.properties below:
mssql.dbname=issueDB
mssql.password=password
mssql.dbserver=localhost
mssql.port=1501
spring.datasource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.datasource.url=jdbc:sqlserver://${mssql.dbserver}:${mssql.port};databaseName=${mssql.dbname}
spring.datasource.username=user
spring.datasource.password=${mssql.password}
spring.flyway.baselineOnMigrate=true
spring.flyway.locations=classpath:db/migration/testissue
spring.flyway.out-of-order=true
spring.flyway.baseline-version=1.3
spring.flyway.placeholder-prefix=$
spring.flyway.placeholder-suffix=$
spring.flyway.mixed=true
spring.flyway.cleanOnValidationError=true
I suppose, it could be caused by this property spring.flyway.cleanOnValidationError=true. According to the docs:
Whether to automatically call clean or not when a validation error occurs.
This is exclusively intended as a convenience for development. Even tough we strongly recommend not to change migration scripts once they have been checked into SCM and run, this provides a way of dealing with this case in a smooth manner. The database will be wiped clean automatically, ensuring that the next migration will bring you back to the state checked into SCM.
May be that you got some validation problems if you are running your application in different ways on the same database and flyway just clean your database and overwrite it with the current scripts state.

How can I reload my changes on Spring Boot without having to restart my server?

I use spring boot 2.0.0 with netbeans 8.2 and gradle.
I use
compile('org.springframework.boot:spring-boot-devtools')
How to avoid to restart every time server when i do a change in the code ?
Are you looking to reload the changes still?
If so you would need to look at another technology like JRebel which can reload without a restart.
https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-devtools.html#using-boot-devtools-restart
However, for just disabling the restart ,
spring.devtools.restart.enabled=false can be set within a properties file. There is a gotcha to disable it completely which requires a system property set, documented here
https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-devtools.html#using-boot-devtools-restart-disable
I think the only solution is JRebel, but it's not free.
Using dev-tools will make your restart faster and automatic, but will not eliminate it. In my Spring Boot/AngularJS projects I use dev-tools + LiveReload (to reload HTML/JavaScript files dynamically) and I'm quite satisfied.

Spring-Boot Vaadin deploy project on jetty

How to deploy a Spring boot vaadin project on jetty using intellij, the Idea behind that is to refresh the project after each changes without restarting the server.
I don't really understand the people who downvote a question without answering it. however here is the answer:
in Spring framework using spring-dev-tools, you have the option to deploy the project whenever the class path changes( in intellij the class path change event is triggered when we rebuild the project, in eclipse class path change event is triggered as soon as we hit the save file of any class). Server will restart (tomcat or jetty) and load the project (Restart method).
we could overcome this expensive approach using third party plug-ins such as JRebel. JRebel will only deploy the class that has been changed.
consider developing a web app and consider making about 100 runs a day, everytime the server restarts it consumes 3 seconds. do the math

Resources