spring-projects / spring-loaded

Java agent that enables class reloading in a running JVM
Apache License 2.0
2.72k stars 515 forks source link

Maven multi-module projects #70

Open LMnet opened 10 years ago

LMnet commented 10 years ago

I'm trying to use spring-loaded on maven multi-module project. Simplified structure:

parent
|-- war project
`-- jar project

War project has jar project in maven dependencies. War project deployed in Tomcat with spring-loaded java agent. IDE - Intellij IDEA. When I modify code in war project, IDE compile .java files in .class files and place this files in 'classes' folder and spring-loaded successfully reload this code. But when I modify code in jar project, hot reload didn't work, because jar project locate in 'lib' folder in builded war as *.jar file. I know, that spring-loaded can't reload jar files, but maybe I can modify my build somehow? Any tips?

rvowles commented 10 years ago

Don't use multi-module builds? Thats an easy one.

LMnet commented 10 years ago

It's not an option for me. My project is very old and I can't change it structure.

padcom commented 10 years ago

First of all not using multiple modules for any application bigger than a hello-world is kinda insane from maintainability perspective - so good that you have it separated. I think it'd be a great feature of spring loaded to support reloading classes from set of predefined (or automatically-guessed maybe? Maven/Gradle?) locations instead of just from the single folder that it does at the moment.

rvowles commented 10 years ago

Multi-module != multiple module. Multi-module is a specific reactor abuse anti pattern endemic to Maven and encouraged in Gradle.

Spring loaded does load from multiple locations? Anything on the class path? On 16 Jul 2014 23:19, "Matthias Hryniszak" notifications@github.com wrote:

First of all not using multiple modules for any application bigger than a hello-world is kinda insane from maintainability perspective - so good that you have it separated. I think it'd be a great feature of spring loaded to support reloading classes from set of predefined (or automatically-guessed maybe? Maven/Gradle?) locations instead of just from the single folder that it does at the moment.

— Reply to this email directly or view it on GitHub https://github.com/spring-projects/spring-loaded/issues/70#issuecomment-49152075 .

LMnet commented 10 years ago

Almost all java projects builds with maven use multi-module projects. You can love it or not, but it's reality. And now, we talking about spring-loaded, not about maven.

By the way - JRebel can handle multi-module projects.

rvowles commented 10 years ago

He asked for solutions, the easiest one is to not used a bad practice.

JRebel you pay for. Spring Loaded is free - there is no reason you can't create a patch.

On Thu, Jul 17, 2014 at 2:44 PM, LMnet notifications@github.com wrote:

Almost all java projects builds with maven use multi-module projects. You can love it or not, but it's reality. And now, we talking about spring-loaded, not about maven.

By the way - JRebel can handle multi-module projects.

— Reply to this email directly or view it on GitHub https://github.com/spring-projects/spring-loaded/issues/70#issuecomment-49252871 .


Richard Vowles, Groovy, Java, Javascript, AngularJS

ph: +64275467747, web: www.google.com/+RichardVowles

presoft commented 9 years ago

I propose a workaround if you are using a Linux machine: i.e. if you have two modules core and website

you can run lsyncd -delay 0 -rsync /path-to-core/target/classes /path-to-website/target/website-extracted/WEB-INF/classes

This will keep syncing you class files from core to website.

Next thing you can add below line to /path-to-tomcat/bin/setenv.sh

rm /path-to-website/target/website-extracted/WEB-INF/lib/core-BUILD-0.1.jar

This would remove the jar file before apache tomcat starts.

Hope this helps.

todoubaba commented 9 years ago

The issue is still open, it really slow me down

padcom commented 9 years ago

I propose we stop complaining about this and create a pull request to implement this. Otherwise JRebel (I'm not affiliated but I am an active user and I'm loving it) does the job.

2015-03-24 2:12 GMT+01:00 todoubaba notifications@github.com:

The issue is still open, it really slow me down

— Reply to this email directly or view it on GitHub https://github.com/spring-projects/spring-loaded/issues/70#issuecomment-85275290 .

yohanliyanage commented 9 years ago

+1 for this enhancement.

aclement commented 9 years ago

1.2.4 dev builds now support a basic form of watching and reloading from jar files. Use the option watchJars. For example:

-Dspringloaded=watchJars=foo.jar:bar.jar

will cause classes loaded from foo.jar and bar.jar to be considered reloadable and those jars will be watched. If the timestamps of the classes being watched within those jars changes, they will be reloaded. Note jars are not fully qualified paths.

amuniz commented 9 years ago

Nice! Thanks!

tmattsson commented 9 years ago

If you're using IntelliJ and developing a web project you can configure the output layout of your artifact to put the compile output of your jar module into WEB-INF/classes. They'll then be seen by spring loaded and reloaded.

File > Project Structure... > Artifacts > select your artifact > on the Output Layout tab remove the module form WEB-INF/lib and add it to WEB-INF/classes.

When you reimport maven projects, after adding dependencies for instance, IntelliJ configures the artifact again and the change is lost, so you need to remember to redo it afterwards.

todoubaba commented 9 years ago

@aclement any update on this issue?

aclement commented 9 years ago

Not sure why I didn't mention this before but spring loaded has had a rebasepaths option for a while, this allows it to load from location X but watch location Y for changes. Maybe it can help here, maybe not. Something like:

-Dspringloaded=rebasePaths=/a/b/c=/d/e/f

Now when things are loaded /a/b/c/com/foo/MyClass.class, it will watch the file at /d/e/f/com/foo/MyClass.class. Multiple path mappings can be passed (comma separated).

Or at least that is the principal, I'm not sure there are lots of regression tests for it...

graemerocher commented 9 years ago

@aclement Does that mean a class can be loaded from a JAR but watch for changes from another path?

aclement commented 9 years ago

watchJars was added later - I haven't tried them together but I think there is a bit of work to do to connect the two pieces so they work properly together. Do you need it?

graemerocher commented 9 years ago

well, one of the issues we have is that when you run a multi-project build with Gradle, Gradle will build all dependency jars and place them in the classpath of the app. The classes are loaded from these JARs. However, users have the expectation that changing a class in a separate subproject to the one you have run that is part of the same multi-project build will result in the class being changed.

The problem is because the class is loaded from a JAR built by Gradle changes to the class in the project are not picked up. One solution would be to have the ability to specify for a particular JAR to watch for changes in a separate directory, that way we don't have to rebuild the JAR to get the changes picked up.

Note this is not an issue when you run a Grails project from the IDE, as an IDE like Intellij will not build the JAR files, but instead place the classes of the subprojects on the classpath directly.

sunilpoudel123 commented 5 years ago

I have a problem, my multi-module project is finely running inside IntelliJ build but when I made an executable jar file from maven, the only index file run but all other classes didn't work, why?