spring-boot:run hot reload with multi module maven project
benneq opened this issue ยท 9 comments
When I try to run my app by using only mvn spring-boot:run
it complains, that it can't find the JAR files of my other modules. Which is kinda clear from a Maven's perspective.
Though I have to run cd parent && mvn clean install && cd ../webapp && mvn spring-boot:run
.
But now it uses the compiled JAR files, and this makes hot reload impossible for everything that's not within the webapp module.
Is there a way, to tell Maven and/or the spring-boot-maven-plugin to just use the dependencies as they are, so it can work without precompiled JAR files, and enable hot reloading this way?
Or is there another way to get hot reload working while using plain maven from the terminal? (Eclipse is not an option, because our front-end team want to use some other editor and Eclipse only recognizes file changes when you switch back to Eclipse, open the file you edited and wait a few seconds)
We use a flat Maven module hierarchy:
parent (pom), module1 (jar), module2 (jar), webapp (war)
First, yes, you must invoke the plugin from the module where you application is located (this is not a Spring Boot limitation, maven just works that way).
Let me see if I understand what you're asking. You have 4 sibling modules and when you run mvn spring-boot:run
in the webapp
modules, you'd like the Spring Boot plugin to take the target/classes
content of module1
and module2
rather than their jar counter-part.
The problem with this approach is that you have absolutely no guarantee that it will be consistent. You may have generated code in target/generated-whatever
or a custom setup of the maven-jar-plugin
.
Running the app from within the IDE sounds like the most practicable option for me.
Well I disagree on the point that the IDE is the most practicable option. My team is divided into frontend and backend. So the frontend team want to use another IDE than the backend team.
You may disagree on the "operational" side but on the technical side, this is definitely the most practicable option. I actually don't know of any other infrastructure (forget Spring Boot) that provides this feature. If you know a Maven plugin that does that, that would obviously help.
Also the cut between frontend/backend is a bit mysterious to me if they're starting up the same app...
I know the maven-shade-plugin
, that can kinda copy all the resulting .class
files (and other resources) into the final build. But that's not the solution to the problem, because it's a copy and then you'd need to edit all resource files in 2 locations (1 for hot reload and 1 for the real build process).
I thought of something like the maven-shade-plugin
, but: it should not copy the files, instead it should create softlinks. So I can edit module1/src/main/resources/foo.html
and the changes will just show up under the softlink webapp/src/main/resources/foo.html
.
Of course the problem is, that we cannot create 5 softlinks from [module1|module2|...]/src/main/resources
to webapp/src/main/resources
.
Btw: Our current app design is like this: There's an Addressbook module, within it are frontend (src/main/resources) and backend (src/main/java). The webapp
combines all those modules. Java development works well with Eclipse, but JS / Angular / CSS / HTML5 is not that nice. Currently the frontend can't be separated from backend, because there are some freemarker scripts needed.
If you're using IntelliJ IDEA, you might want to try auto-reload with SB1.3
https://youtrack.jetbrains.com/issue/IDEA-141638
jetty-maven-plugin
supports reloading a module when one of its siblings has changed. Example: http://stackoverflow.com/questions/25725552/maven-jetty-plugin-automatic-reload-using-a-multi-module-project
A couple of suggestions.
You could run the plugin without cd'ing by doing the following:
mvn -pl webapp spring-boot:run
Regarding running expanded module dependencies, related is http://stackoverflow.com/questions/11091311/maven-execjava-goal-on-a-multi-module-project. It looks like this might work here as well, perhaps best with a profile: http://stackoverflow.com/a/11094503/527333
Other similiar:
I was able to get this working like so:
In parent pom:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
In webapp
pom:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
<skip>false</skip>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
Execute in project root:
mvn -pl webapp -am spring-boot:run
Thanks to @btiernay! But it also works with the usual mvn spring-boot:run
, have a look at the demo project I've just created: https://github.com/drahkrub/spring-boot-multi-module