You can but you need some manual coding, as default servlet (part of container /tomcat/ that serves static resources) does know nothing about your jars. You need to
- implement your own servlet that can read data from classpath
- map it to some URL
- use URL in JSP with some parameter / path identifying the requested file
I implemented simple prototype, it does handle only CSS files and it does not cover any corner cases. But it works and you can extend it as you need:
Servlet is simple, it just takes part or URL behind its mapping and loads resource from classpath (e.g. jar):
package cz.literak.demo; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; public class JarServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String path = request.getPathInfo(); setContentType(path, response); InputStream streamIn = null; try { streamIn = getClass().getResourceAsStream(path); PrintWriter writer = response.getWriter(); int c; while ((c = streamIn.read()) != -1) { writer.write(c); } } catch (IOException e) { streamIn.close(); } } private void setContentType(String path, HttpServletResponse response) { if (path.toLowerCase().endsWith(".css")) { response.setContentType("text/css"); } // TODO other mime types } }
You need to register the servlet and its mapping:
<servlet> <servlet-name>JarDefault</servlet-name> <servlet-class>cz.literak.demo.JarServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>JarDefault</servlet-name> <url-pattern>/jar/*</url-pattern> </servlet-mapping>
And you can use it this way:
<link rel="stylesheet" type="text/css" href="jar/styles/layout.css"/>
I copied file layout.css under directory styles in one jar that is part of my war. Easy, is not it?