7

I have a Spring Boot web application packaged as a WAR file and I wish to have the ability to run some tasks (scripts or commands) on-demand. For example:

  • Initialize the database schema
  • Seed the database programmatically
  • Data migration when required for new versions of the application (move files, database operations, etc.)
  • Validate data integrity between stored files and database contents

These "commands" would be much easier to implement if they had access to the same beans (services, DAOs) and models as the web app proper. I expect I have to create a Spring application context somewhere for this to happen. I would also prefer to package these commands with the rest of the application so they are tested alongside it and easy to deploy.

Essentially, I want to know how to achieve something similar to Laravel's artisan commands (PHP).

I have read on running a class inside a WAR here and here. I'm searching for the "Spring way" of packaging and running commands. Do I have to integrate Spring Batch jobs for this? From what I understand, Spring Batch is meant for larger workloads which can be split in multiple batches. Should I bite the bullet and put the commands in a second separate maven module which references the first one?

update

I implemented an ApplicationRunner (thanks Stefan!) to see how they work and found that they run after the Spring application context is refreshed. This means that the whole web application is initialized and active before the runner executes. This includes MVC endpoint mappers and scheduled tasks defined in configurations. While this can definitely be useful, I need to run commands when all that is not active because it can come in conflict with the commands (especially with transient data states during command runs).

update 2

I simply needed to create another executable jar that creates a Spring Boot application using a CommandLineRunner. This can reference all the beans from the web application if I use 3 modules:

  1. The spring "service" beans module
  2. The web application module
  3. The command line runner module
bernie
  • 9,820
  • 5
  • 62
  • 92

2 Answers2

4

You can use ApplicationRunner see spring boot application runner. The runners are executed after the app started and you have access to the spring context.

The CommandLineRunner class is used precisely for this. See also How does a Spring Boot console based application work?

bernie
  • 9,820
  • 5
  • 62
  • 92
0

By using spring data jpa you can easily achieve this

1-By developing your entity classes which represent your database schema and set the property spring.jpa.hibernate.ddl-auto=create, the schema will created for you when you run the application(be careful, because each time you run the schema will be dropped and recreated for you)

2-you can include whatever sql statements in an import.sql which should be placed in resources folder with configuration file(it's a hibernate feature but still works pretty fine with spring).

initialize database with jpa

initialize database with hibernate

Shady Ragab
  • 705
  • 10
  • 26
  • But all this techniques are typically used in development and test environment or in a production environment for the first deployment only.If you need more advanced migration tool which do some kind of version control to your DB, so to speak, track various changes in your development environment to be applied in your production environment, you can have a look on [flyway](https://flywaydb.org/) – Shady Ragab Sep 19 '16 at 22:58
  • Thanks for the suggestion, but it does not achieve my stated goals. First of all, I don't use JPA or Hibernate. Second, I need something more generic than a tool to run SQL queries since I need to do some file IO as well, compute values, etc. – bernie Sep 20 '16 at 14:02