When I run my Spring Boot application (from within Intellij IDEA) and either trigger a stop, restart or automatic redeploy of the application; something is issuing a shutdown command to my HSQLDB.
I run a HSQLDB (v.2.3.4) in Server mode from an external terminal window.
HSQLDB Server log at the moment I restart or stop my Spring Boot application:
[Server#4f023edb]: Initiating shutdown sequence...
[Server#4f023edb]: Shutdown sequence completed in 101 ms.
[Server#4f023edb]: 2017-05-05 21:47:01.878 SHUTDOWN : System.exit() is called next
This is of course very annoying since I have to go through the hassle of manually bringing up my HSQLDB every time I redeploy the application. How do I prevent this from happening, or an explanation of what is actually going on.
This only seems to happen when running the Spring Boot application from within Intellij IDEA, if I start the Spring Boot application-jar from a terminal window and issue shutdown Ctrl+C, then HSQLDB is not affected.
Turns out the reason why I only experience this problem when running from within Intellij IDEA is because spring-boot-devtools (a maven dependency included in my project) is not packaged in the application-jar that I run from a terminal window.
Developer tools are automatically disabled when running a fully packaged application. If your application is launched using java -jar or if it’s started using a special classloader, then it is considered a “production application”. Flagging the dependency as optional is a best practice that prevents devtools from being transitively applied to other modules using your project. Gradle does not support optional dependencies out-of-the-box so you may want to have a look to the propdeps-plugin in the meantime.
spring-boot-devtools is active when running the application from within Intellij IDEA and provides a shutdown hook that will try to gracefully shutdown the database resource (amongst other things).
The shutdown hook can be disabled the following way;
SpringApplication app = new SpringApplication(MyApplication.class);
app.setRegisterShutdownHook(false); //This disables the shutdown hook
app.run(args);
This solution resolved the problem I had.
Related
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.
I have an Eclipse RCP(E4) application, which I can start without any problem. Now I decide to connect it to my Spring-Boot embedded Tomcat-server. The Spring-Boot-container runs an H2 as an in memory DB. Running Spring-Boot as "Java Application", I access the data in the DB via a rest-service over the browser.
The problem is, I actually want to embed the Spring-Boot part in my RCP-application. So once I start the application it will start my embedded Sring-Boot tomcat and I can run my CRUD-operations directly from the RCP-UI.
Has anyone got experience dealing with Eclipse-RCP running with Spring-Boot?
P.S: I chose explicitly to not put any code hier, because I don't have any code problem yet. The applications run separately well. I just haven't no clue how to relate them.
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.
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.
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.