Live Edit in Vert.x 3 and IntelliJ
If you’re using Vert.x 3 and Handlebars you probably want live class, static resources and template reloads. This post will explain how to acheive that.
I’m running my app as follows, but any way of starting should work:
public static void main(String[] args) {
Vertx vertx = Vertx.vertx();
vertx.deployVerticle(Application.class.getName());
}
How Vert.x Handles Files #
First its’ important to understand that Vert.x will look through the classpath for resources, even if it looks like it’s only using files internally at first glance.
The way Vert.x finds resources in the classpath is through its FileResolver
(snippets from Vert.x 3.2.1):
// First look for file with that name on disk
File file = new File(fileName);
if (cwd != null && !file.isAbsolute()) {
file = new File(cwd, fileName);
}
if (!ENABLE_CP_RESOLVING) {
return file;
}
if (!file.exists()) {
// Look for it in local file cache
File cacheFile = new File(cacheDir, fileName);
if (ENABLE_CACHING && cacheFile.exists()) {
return cacheFile;
}
// Look for file on classpath
ClassLoader cl = getClassLoader();
...
Basic Usage of Templates #
I’m using Handlebars, so I’m using it in this example, but any template engine should work.
Put your handlebar files in the resources dir, for example src/main/resources/index.hbs
. Then load the template like this:
templateEngine.render(ctx, "index.hbs", event -> {
if (event.failed()) {
ctx.fail(event.cause());
}
ctx.response().end(event.result());
});
Basic Usage of Static Resources #
Put static resources in src/main/resources/webroot
, for example src/main/resources/webroot/logo.png
. Then register a route for static resources:
rootRouter.route("/static/*").handler(StaticHandler.create());
Now, just access the static resources from your html:
<img src="/static/logo.png"/>
Automatic Reloading #
Disable File Cache #
Step one is to disable the vert.x file cache. This cache will prevent reloading from the classpath. Set the sysprop -Dvertx.disableFileCaching=true
, either on command line or in code and you’re set.
Please note that this will not prevent vert.x from actually saving files in the file cache dir at ($(pwd)/.vertx
), only that it will overwrite the cache entries every time. From FileResolver
again:
if (ENABLE_CACHING) {
Files.copy(resource.toPath(), cacheFile.toPath());
} else {
Files.copy(resource.toPath(), cacheFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
So don’t be surprised if you still see files in $(pwd)/.vertx
with this setting.
Disable Template Engine Cache #
Step two is to disable Handlebars cache:
HandlebarsTemplateEngine templateEngine = HandlebarsTemplateEngine.create();
templateEngine.setMaxCacheSize(0);
Remeber to Rebuild Project in IntelliJ #
Step three is to remember that IntelliJ doesn’t copy the files to target/classes (assuming maven) unless you recompile the project.
With this setup you can edit your handlebar template, press Ctrl+F9
and reload the web page. Works for classes, templates and static resources. Voilà!
Troubleshooting #
Make sure that you have set the vertx.disableFileCache
property to true
. Delete the file cache by rm .vertx/*
. Make a change in the source template. Recompile the project. First verify that you see the change in target/classes/index.hbs
. Then verify that you see the change in .vertx/file-cache-<guid>/index.hbs
. Hard reload browser (Ctrl+F5). Should work.