Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maven Webjars are not found

I'm trying to use webjars for bootstrap based on their documentation

<dependencies>
    <dependency>
        <groupId>org.webjars</groupId>
        <artifactId>bootstrap</artifactId>
        <version>3.1.0</version>
    </dependency>
</dependencies>

This is how I start the server.

public static void main(String[] args) throws Exception {
        final Server server = createServer();
        try {
            server.start();
            server.join();
        } finally {
            server.destroy();
        }
    }
private static Server createServer() throws Exception {
        final int serverPort = getServerPort();

        final Server server = new Server(serverPort);
        final HandlerList  servletContextHandlers = new HandlerList();
        servletContextHandlers.addHandler(buildServletContextHandler());
        server.setHandler(servletContextHandlers);

        return server;
    }

    private static ServletContextHandler buildServletContextHandler() throws ConfigurationException {
        final ResourceConfig resourceConfig = new ResourceConfig();
        resourceConfig.register(new CustomApiBinder());
        resourceConfig.packages("com.foo.api");

        final ServletHolder servletHolder = new ServletHolder(new ServletContainer(resourceConfig));

        final ServletContextHandler servletContextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
        servletContextHandler.setContextPath("/api");
        servletContextHandler.addServlet(servletHolder, "/*");

        return servletContextHandler;
    }

Then when I try to link the bootstrap css sheet, I get a file not found error

<link rel='stylesheet' href='webjars/bootstrap/3.1.0/css/bootstrap.min.css'>

Do I need a special handler for that? From the documentation, it says that if you use servlet 3, you don't need anything else.

Does anyone have an example without using Spring?

Jetty 9.4.9.v20180320

Jersey 2.26

like image 686
Marc Avatar asked Oct 14 '25 06:10

Marc


1 Answers

The bootstrap-<ver>.jar has a META-INF/resources/ subdirectory.

$ jar -tvf bootstrap-4.0.0.jar | grep META-INF/resources
     0 Thu Jan 18 21:20:32 GMT 2018 META-INF/resources/
     0 Thu Jan 18 21:20:32 GMT 2018 META-INF/resources/webjars/
     0 Thu Jan 18 21:20:32 GMT 2018 META-INF/resources/webjars/bootstrap/
     0 Thu Jan 18 21:20:38 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/
     0 Thu Jan 18 21:20:38 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/css/
     0 Thu Jan 18 21:20:38 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/js/
 43852 Thu Jan 18 21:20:38 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/css/bootstrap-grid-jsf.css
  4076 Thu Jan 18 21:20:38 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/css/bootstrap-grid-jsf.css.gz
 43852 Thu Jan 18 11:29:48 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/css/bootstrap-grid.css
  4076 Thu Jan 18 21:20:38 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/css/bootstrap-grid.css.gz
 95910 Thu Jan 18 11:29:48 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/css/bootstrap-grid.css.map
 34243 Thu Jan 18 21:20:38 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/css/bootstrap-grid.min-jsf.css
  3483 Thu Jan 18 21:20:38 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/css/bootstrap-grid.min-jsf.css.gz
 34243 Thu Jan 18 11:29:48 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/css/bootstrap-grid.min.css
  3483 Thu Jan 18 21:20:38 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/css/bootstrap-grid.min.css.gz
 76209 Thu Jan 18 11:29:48 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/css/bootstrap-grid.min.css.map
178152 Thu Jan 18 21:20:38 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/css/bootstrap-jsf.css
 22410 Thu Jan 18 21:20:38 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/css/bootstrap-jsf.css.gz
  4798 Thu Jan 18 21:20:38 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/css/bootstrap-reboot-jsf.css
  1683 Thu Jan 18 21:20:38 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/css/bootstrap-reboot-jsf.css.gz
  4798 Thu Jan 18 11:29:48 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/css/bootstrap-reboot.css
  1683 Thu Jan 18 21:20:38 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/css/bootstrap-reboot.css.gz
 57721 Thu Jan 18 11:29:48 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/css/bootstrap-reboot.css.map
  3936 Thu Jan 18 21:20:38 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/css/bootstrap-reboot.min-jsf.css
  1584 Thu Jan 18 21:20:38 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/css/bootstrap-reboot.min-jsf.css.gz
  3936 Thu Jan 18 11:29:48 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/css/bootstrap-reboot.min.css
  1584 Thu Jan 18 21:20:38 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/css/bootstrap-reboot.min.css.gz
 25881 Thu Jan 18 11:29:48 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/css/bootstrap-reboot.min.css.map
178152 Thu Jan 18 11:29:48 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/css/bootstrap.css
 22410 Thu Jan 18 21:20:38 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/css/bootstrap.css.gz
411645 Thu Jan 18 11:29:48 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/css/bootstrap.css.map
144877 Thu Jan 18 21:20:38 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/css/bootstrap.min-jsf.css
 20563 Thu Jan 18 21:20:38 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/css/bootstrap.min-jsf.css.gz
144877 Thu Jan 18 11:29:48 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/css/bootstrap.min.css
 20563 Thu Jan 18 21:20:38 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/css/bootstrap.min.css.gz
551641 Thu Jan 18 11:29:48 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/css/bootstrap.min.css.map
195855 Thu Jan 18 11:29:48 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/js/bootstrap.bundle.js
 41578 Thu Jan 18 21:20:38 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/js/bootstrap.bundle.js.gz
326634 Thu Jan 18 11:29:48 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/js/bootstrap.bundle.js.map
 67742 Thu Jan 18 11:29:48 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/js/bootstrap.bundle.min.js
 19244 Thu Jan 18 21:20:38 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/js/bootstrap.bundle.min.js.gz
273872 Thu Jan 18 11:29:48 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/js/bootstrap.bundle.min.js.map
115048 Thu Jan 18 11:29:48 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/js/bootstrap.js
 20137 Thu Jan 18 21:20:38 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/js/bootstrap.js.gz
195373 Thu Jan 18 11:29:48 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/js/bootstrap.js.map
 48944 Thu Jan 18 11:29:48 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/js/bootstrap.min.js
 13105 Thu Jan 18 21:20:38 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/js/bootstrap.min.js.gz
161998 Thu Jan 18 11:29:48 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/js/bootstrap.min.js.map
   284 Thu Jan 18 21:20:32 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/webjars-requirejs.js
   182 Thu Jan 18 21:20:38 GMT 2018 META-INF/resources/webjars/bootstrap/4.0.0/webjars-requirejs.js.gz

This kind of JAR is a web resource jar, and for Jetty it's only available when using a full blown WebAppContext.

Note: When using a Jetty WebAppContext all of the WEB-INF/lib/*.jar!/META-INF/resources/ contents will be unpacked into a temporary directory so that Jetty can serve the contents of those special jar files.

You have a few options from here (ordered from best/easiest choice to most complex).

  1. Have maven unpack your META-INF/resources jars into your resources directory, that you then reference by classpath resource URL as the ServletContextHandler resource base location.
  2. Have your own code unpack the META-INF/resources directories into a temporary directory that you then use as a the ServletContextHandler resource base directory.
  3. Change over to using a full blown WebAppContext with a war file and all of the extra configuration necessary to enable the various features you want to use.

Note, if your eventual end goal is to build a jetty uber jar, then option 1 will be the best choice overall.

The choice you make will depend on how you eventually want to package your project up.

  • Will it be 1 self executing jar? Then option 1.
  • Will it be a collection of jars? Then options 1 and 2 are good choices.
  • Will it be a collection of jars and a war file? Then option 3 is a good choice.

The biggest issue with META-INF/resources based content is name collision resolution. Because of this, I encourage you to go with option 1 as this will resolve (at build time) any conflict resolution issues.

Eg: If you have 2 JAR files, both with META-INF/resources/foo.css file (but with different contents) and a request arrives for http://<host>/foo.css, which one do you serve?

For an example of Option 1 see - https://github.com/jetty-project/embedded-jetty-with-web-resources

Some embedded-jetty resources maintained by the Eclipse Jetty project:

  • https://www.eclipse.org/jetty/documentation/9.4.x/embedding-jetty.html
  • https://github.com/jetty-project/embedded-jetty-cookbook
  • https://github.com/eclipse/jetty.project/tree/jetty-9.4.9.v20180320/examples/embedded/
like image 189
Joakim Erdfelt Avatar answered Oct 16 '25 18:10

Joakim Erdfelt



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!