Vertx-web: where do I place webroot folder?

Dave Taubler picture Dave Taubler · Aug 3, 2015 · Viewed 13.5k times · Source

This should be an easy one, but it's not been so far. I've been working with vert.x 2 for a bit and switched to vert.x 3 recently. I thought I'd try a simple vertx-web example but can't get past a simple serving up of static files.

My server class contains the following snippets:

    HttpServer server = vertx.createHttpServer();
    Router router = ...;
    router.route("/static/*").handler(StaticHandler.create().setCachingEnabled(false));
    server.requestHandler(router::accept).listen(ctx.port);

I'm using Eclipse, but have also been trying running vertx from the the command line. I'm also using Maven. I have three webroot folders, and vert.x can find none of them:

myproject/webroot
myproject/src/main/resources/webroot
myproject/src/main/java/webroot

Each of those 'webroot's contains an index.html, and a css/base.css file.

The first one is in my project's root folder. The second is in the Maven resources folder, and the third should be flat-out on my classpath. In my Eclipse run config, I added myproject/src/main/resources/webroot to the classpath, and I made sure my working directory was set to 'myproject'. When running from the command line, I'm in the myproject directory, and my script looks like this:

JAVA_OPTS="-Dmyproject.port=8099" CLASSPATH="src/main/java:src/main/resources:target/dependencies/*:target/classes" vertx run com.my.MyProject

No matter what, I always get 404s when I try any of these URLs:

http://localhost:8099
http://localhost:8099/
http://localhost:8099/index.html
http://localhost:8099/static/css/base.css

Anything else I need to be doing?

Answer

Hoobajoob picture Hoobajoob · Nov 22, 2015

The solution I found depends on the answer to the questions: where is the static content going to be at runtime, and from where would you like vertx to serve it?

In my case, the installed file system would be where the static content was located (not in a jar file), and I wanted vertx to serve it from that location so that it could be updated live. So, I disabled classpath resolving in the StaticHandler by setting the JVM system property vertx.disableFileCPResolving to true at vertx startup.

Then I placed the webroot folder under the directory from which the jvm is started. In my case, I'm using scripts that guarantee the jvm's cwd is always <app-root>/bin, so dropping the content in <app-root>/bin/webroot was sufficient. If you can't make guarantees about where the jvm will be started from, it might be tougher, because you may need to pass an absolute path to StaticHandler.webroot() pointing to this fixed location, but I think there is an open issue regarding support for this (see here).

If the static content is going to be packaged into a jar, it's a little simpler. You can add 'webroot' as a resource in the jar and place all the content of interest in there. In this case you don't want to disable classpath resolving, so either set vertx.disableFileCPResolving to false, or don't set it at all. Now when you run vertx, it will find webroot in the jar file and extract its contents to <cwd>/.vertx/.file-cache-<guid> (where cwd is wherever you started the jvm from), and serve the contents from there. Note that this isn't viable if you intend to be able to do live updates to the content, because any changes to the files under that directory will get lost when vertx shuts down, because vertx-web will delete that directory. On restart, it will retrieve the original files from the jar resource again, and changes will be lost.

Anyway, hope this helps.