Can DropWizard serve assets from outside the jar file?
Asked Answered
B

6

15

In looking at the documentation, it appears that DropWizard is only able to serve static content living in src/main/resources. I'd like to keep my static files in a separate directory outside the jar file. Is that possible? Or do most people use nginx/Apache for their static content?

Bernardinebernardo answered 8/1, 2013 at 20:48 Comment(0)
P
12

yes, it can, using this plugin - https://github.com/bazaarvoice/dropwizard-configurable-assets-bundle

Prevocalic answered 17/1, 2013 at 7:33 Comment(3)
You don't need any plugin. Simply add the document root in the classpath.Compute
Unfortunately this plug-in is aged, and only supports up to 0.7. It may just be a matter of changing to the plugin to use the newer Dropwizard (io.dropwizard) classpath, but I haven't tried. Any other out-of-the-box answer?Mok
Yes, follow the steps outlined in my answer below.Toname
T
7

Working off of Marcello Nuccio's answer, it still took me the better part of my day to get it right, so here is what I did in a bit more detail.

Let's say I have this directory structure:

  • my-dropwizard-server.jar
  • staticdocs
    • assets
      • image.png

Then this is what you have to do to make it work:

1) In your dropwizard Application class, add a new AssetsBundle. If you want your assets to be served from a different URL, change the second parameter.

@Override
public void initialize(Bootstrap<AppConfiguration> bootstrap) {
    bootstrap.addBundle(new AssetsBundle("/assets/", "/assets/"));       
}

2) Add the document root to your classpath by configuring the maven-jar-plugin like this. (Getting the "./staticdocs/" in the correct form took me a while. Classpaths are unforgiving.)

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-jar-plugin</artifactId>
  <version>2.4</version>
  <configuration>
    <archive>
      <manifest>
        <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
        <addClasspath>true</addClasspath>
      </manifest>
      <manifestEntries>
        <Class-Path>./staticdocs/</Class-Path>
      </manifestEntries>
    </archive>
  </configuration>
</plugin>

3) This step is entirely optional. If you want to serve your Jersey REST Resources from a different root path (e.g. "app"), add the following to your configuration YML:

server:
  rootPath: /app/*

Now you can access your static content like this, for example:

localhost:8080/assets/image.png
Toname answered 12/6, 2015 at 9:14 Comment(3)
you can avoid the use of maven-jar-plugin by putting the assets folder in the src/main/resources.Compute
But that will package the assets into the jar, won't it? The whole point of this question is to serve the assets from OUTSIDE of the jar.Toname
you are right. The important point is: put your assets wherever you like, but make sure they are found in the classpath. This is the only requirement.Compute
C
4

The user manual says:

use an extended AssetsBundle constructor to serve resources in the assets folder from the root path.

i.e. the files are loaded as resources from the classpath. Then you only need to properly set the classpath for the service.

With the default configuration, this means that you need to call the document root assets, and put the parent folder of the document root in the classpath. Then, for example, assets/foo.html will be available at

http://localhost:8080/assets/foo.html
Compute answered 6/3, 2014 at 10:9 Comment(4)
This is fine if your static assets really are html files. If they are large, binary, or compressed files, it's best to keep them outside the jar file.Capon
@CraigP.Motlin, The big advantage of single jar file is ease of deployment: just copy a single file and everything is updated and guaranteed to work as on staging server. Often the biggest drawback is the need to upload a big file on the production server. To workaround this, I use rsync to update an intermediate copy of the latest deployed file. This is very fast and reliable.Compute
@CraigP.Motlin, to clarify: I am not saying to put all assets in the jar. As I have said in my answer, you only need to add the assets folder to the classpath. In other words: put the assets folder wherever you like, the only requirement is that it is found in the classpath.Compute
I see. The Dropwizard documentation recommends creating shaded jars, meaning everything on the classpath is in the shaded jar in many apps. But you can also take more fine-grained control of the classpath.Capon
T
3

There is a upto-date dropwizard-configurable-assets-bundle maintained at official dropwizard-bundles. You can find it at github https://github.com/dropwizard-bundles/dropwizard-configurable-assets-bundle. Current version supports dropwizard 0.9.2

This can be used to serve static files from arbitrary file system path.

Torbert answered 30/6, 2016 at 9:59 Comment(0)
E
2

The vast majority of websites that serve static content do so through a dedicated webserver, or, at larger scale, a CDN.

Occasionally, you might want to deploy an application as a self-contained unit complete with all assets which is where Dropwizard comes in.

It is possible to get Dropwizard to serve up assets from outside the classpath, but the easiest way to do this is to write your own asset endpoint that reads from an externally configured file path.

East answered 15/1, 2013 at 17:9 Comment(0)
D
1

To complement craddack's answer: Correct, you can use the regular AssetsBundle as long as you add the assets to your classpath. If you use gradle and oneJar, you can add a directory to the classpath in the oneJar task:

task oneJar(type: OneJar) {
  mainClass = '...'
  additionalDir = file('...')
  manifest {
    attributes 'Class-Path': '.. here goes the directory ..'
  }
}

see https://github.com/rholder/gradle-one-jar

Debunk answered 12/6, 2015 at 13:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.