Intro
Aim of this article is to help you reduce delay between writing code and seeing the results in Java.
Background: I have been coding Java in backend and JavaScript in fronted for ages, and have grown accustomed to test things in JavaScript with livereload, but was not doing enough of that in Java.
Disclaimer: I am not a fan of TDD, and amount of test I write depends on time I got and also on my mood at the time. Even if you do not write many tests you can see how playing with some pieces of code and seeing results immediately can be useful.
How ?
Steps are really simple.
- run in DEBUG mode
- collect list of files to watch
- run a thread to watch for changes
- wait for a bit (100ms is reasonable) for hot-code-replace to kick in
- re-run your code
- continue looping until files change
package hr.hrg.livetest4j;
import java.io.File;
public class BasicExample {
public static void main(String[] args) {
new Thread(()->{
File[] files = {new File("target/test-classes/hr/hrg/livetest4j/BasicExample.class")};
long lastMod = 0;
while(!Thread.interrupted()) {
try {
long mod = lastMod;
for(File file:files) {
if(!file.exists()) {
System.err.println("file not found "+file.getAbsolutePath());
return;
}
mod = Math.max(mod, file.lastModified());
}
if(mod != lastMod) {
// wait a bit more for hot-code-replace to kick in
Thread.sleep(100);
test();// run this on change
}
lastMod = mod;
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
static void test(){
System.out.println("Hello basic 1");
}
}
Location of class files may be different depending on your IDE setup, and common ones are:
target/classes
target/test-classes
bin
LiveTest4j utility
https://github.com/hrgdavor/livetest4j
For now I do not plan to package it as maven dependency. It is simple enough to copy the Utility class from the project into your own project with other test classes.
It started rather simple like the basic example above, but I have added few nice things so it is more usable in general.
After you copy LiveTest4j.java to your project create a new file and simply use it like this:
public class LiveTestSimple {
public static void main(String[] args) throws Exception{
new LiveTest4j(()->{
System.out.println("Hello live 1");
})
.run();
}
}
Run you class in debug mode, change something , save and watch the magic happen!
The utility has some nice things
- it can extract class info from lambda to automatically add class file to watch list
- uses few common paths to search for generated class (and you can add your own)
- has debug mode detection to warn you if you mistakenly run it normally
- has an annotation to declare dependencies (classes,files) to add to watch list
This can be very useful for specific use-cases, and if you like the benefits you can go further
- run a specialised agent that allows more advanced code replace (built-in code reload is limited to method bodies)
- setup live reload in Spring
- use a commercial solution like JRebel
Feedback
All feedback how to improve the utility are welcome, also further resources on this topic as well.
I tested this only in eclipse, so it would be great you can try it in your favourite editor and see if advanced things like debug mode detection works.
Top comments (0)