title: Serving static files with jetty in karaf (outside of bundle)
body: <p>we are struggling with the simple issue of serving static files from somewhere in the filesystem but outside of the web application, but we can't get it running.</p>
  
  <p>There are sever examples on how to do this, but none of them seem to work and so far we couldn't find a confirmation from someone that it actually does work.</p>
  
  <p>The jetty.xml found in the etc directory has been edited as it is stated 
  here
  <a href="https://ops4j1.jira.com/wiki/display/paxweb/Advanced+Jetty+Configuration" rel="nofollow">https://ops4j1.jira.com/wiki/display/paxweb/Advanced+Jetty+Configuration</a>
  or here
  <a href="https://github.com/ops4j/org.ops4j.pax.web/blob/master/samples/jetty-config-fragment/src/main/resources/jetty.xml" rel="nofollow">ops4j GitHub sample</a></p>
  
  <p>So added to jetty.xml this:</p>
  
  <pre><code>&lt;Get name="handler"&gt;
          &lt;Call name="addHandler"&gt;
              &lt;Arg&gt;
                  &lt;New class="org.eclipse.jetty.servlet.ServletContextHandler"&gt;
                      &lt;Set name="contextPath"&gt;/fileserver&lt;/Set&gt;
                      &lt;Set name="resourceBase"&gt;/Users/Shared/testenv&lt;/Set&gt;
                      &lt;Call name="addServlet"&gt;
                          &lt;Arg&gt;org.eclipse.jetty.servlet.DefaultServlet&lt;/Arg&gt;
                          &lt;Arg&gt;/&lt;/Arg&gt;
                      &lt;/Call&gt;
                  &lt;/New&gt;
              &lt;/Arg&gt;
          &lt;/Call&gt;
      &lt;/Get&gt;
  </code></pre>
  
  <p>or this:</p>
  
  <pre><code>&lt;Get name="handler"&gt;
          &lt;Call name="addHandler"&gt;
              &lt;Arg&gt;
                  &lt;New class="org.eclipse.jetty.server.handler.ContextHandler"&gt;
                      &lt;Set name="contextPath"&gt;/fileserver&lt;/Set&gt;
                      &lt;Set name="handler"&gt;
                          &lt;New class="org.eclipse.jetty.server.handler.ResourceHandler"&gt;
                              &lt;Set name="resourceBase"&gt;/Users/Shared/testenv&lt;/Set&gt;
                              &lt;Set name="directoriesListed"&gt;true&lt;/Set&gt;
                          &lt;/New&gt;
                      &lt;/Set&gt;
                  &lt;/New&gt;
              &lt;/Arg&gt;
          &lt;/Call&gt;
      &lt;/Get&gt;
  </code></pre>
  
  <p>With both versions jetty / karaf starts up fine and when karaf is shut down I can see</p>
  
  <blockquote>
    <p>2015-06-02 12:02:57,838 | INFO  | pool-7-thread-2  | ContextHandler<br>
    | 113 - org.eclipse.jetty.aggregate.jetty-all-server -
    8.1.15.v20140411 | stopped o.e.j.s.ServletContextHandler{/fileserver,file:/Users/Shared/testenv/}</p>
  </blockquote>
  
  <p>But the files are not served under localhost:8181/fileserver</p>
  
  <p>The only way it is working (in a freshly installed karaf container) is to use</p>
  
  <pre><code>&lt;Set name="handler"&gt;
          &lt;New class="org.eclipse.jetty.server.handler.HandlerList"&gt;
              &lt;Set name="handlers"&gt;
                  &lt;Array type="org.eclipse.jetty.server.Handler"&gt;
                      &lt;Item&gt;
                          &lt;New class="org.eclipse.jetty.servlet.ServletContextHandler"&gt;
                              &lt;Set name="contextPath"&gt;/fileserver&lt;/Set&gt;
                              &lt;Set name="resourceBase"&gt;/Users/Shared/testenv&lt;/Set&gt;
                              &lt;Call name="addServlet"&gt;
                                  &lt;Arg&gt;org.eclipse.jetty.servlet.DefaultServlet&lt;/Arg&gt;
                                  &lt;Arg&gt;/&lt;/Arg&gt;
                              &lt;/Call&gt;
                          &lt;/New&gt;
                      &lt;/Item&gt;
                  &lt;/Array&gt;
              &lt;/Set&gt;
          &lt;/New&gt;
      &lt;/Set&gt;
  </code></pre>
  
  <p>But doing this, will break other web applications running in karaf. For example we are using the Camel Servlet component. </p>
  
  <p>So does someone has a working configuration of serving static files through jetty instance in karaf or now how to do this? </p>
  
  <p>Any help appreciated. Thank in advance!</p>
  
  <p>By the way: Using Karaf 3.0.3 </p>
  
  <p>EDIT:</p>
  
  <p>I rerun the test with the snippet given by Achim and enabled DEBUG loggin.</p>
  
  <blockquote>
    <p>2015-06-03 15:33:25,492 | DEBUG | pool-6-thread-1  | XmlConfiguration 
    | 71 - org.eclipse.jetty.aggregate.jetty-all-server - 8.1.15.v20140411
    | XML o.e.j.s.h.ContextHandler{/,null}.setContextPath(/static-content)
    2015-06-03 15:33:25,527 | DEBUG | pool-6-thread-1  | XmlConfiguration 
    | 71 - org.eclipse.jetty.aggregate.jetty-all-server - 8.1.15.v20140411
    | XML
    o.e.j.s.h.ContextHandler{/static-content,null}.setHandler(org.eclipse.jetty.server.handler.ResourceHandler@3855ace4)
    2015-06-03 15:33:25,529 | DEBUG | pool-6-thread-1  | Container<br>
    | 71 - org.eclipse.jetty.aggregate.jetty-all-server - 8.1.15.v20140411
    | Container o.e.j.s.h.ContextHandler{/static-content,null} +
    org.eclipse.jetty.server.handler.ResourceHandler@3855ace4 as handler
    2015-06-03 15:33:25,529 | DEBUG | pool-6-thread-1  | Container<br>
    | 71 - org.eclipse.jetty.aggregate.jetty-all-server - 8.1.15.v20140411
    | Container
    org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection@6665534e
    + o.e.j.s.h.ContextHandler{/static-content,null} as handler 2015-06-03 15:33:25,542 | DEBUG | pool-6-thread-1  | AbstractLifeCycle<br>
    | 71 - org.eclipse.jetty.aggregate.jetty-all-server - 8.1.15.v20140411
    | starting o.e.j.s.h.ContextHandler{/static-content,null} 2015-06-03
    15:33:25,542 | DEBUG | pool-6-thread-1  | AbstractHandler<br>
    | 71 - org.eclipse.jetty.aggregate.jetty-all-server - 8.1.15.v20140411
    | starting o.e.j.s.h.ContextHandler{/static-content,null} 2015-06-03
    15:33:25,543 | DEBUG | pool-6-thread-1  | AbstractLifeCycle<br>
    | 71 - org.eclipse.jetty.aggregate.jetty-all-server - 8.1.15.v20140411
    | STARTED o.e.j.s.h.ContextHandler{/static-content,null} 2015-06-03
    15:34:27,974 | DEBUG |  /static-content | Server<br>
    | 71 - org.eclipse.jetty.aggregate.jetty-all-server - 8.1.15.v20140411
    | REQUEST /static-content on
    AsyncHttpConnection@638f2d20,g=HttpGenerator{s=0,h=-1,b=-1,c=-1},p=HttpParser{s=-5,l=10,c=0},r=1
    2015-06-03 15:34:27,974 | DEBUG |  /static-content | ServerModel<br>
    | 78 - org.ops4j.pax.web.pax-web-spi - 3.1.4 | Matching
    [/static-content]... 2015-06-03 15:34:27,975 | DEBUG | 
    /static-content | ServerModel                      | 78 -
    org.ops4j.pax.web.pax-web-spi - 3.1.4 | Path [/static-content] does
    not match any context 2015-06-03 15:34:27,975 | DEBUG | 
    /static-content | Server                           | 71 -
    org.eclipse.jetty.aggregate.jetty-all-server - 8.1.15.v20140411 |
    RESPONSE /static-content  200 handled=false</p>
  </blockquote>
  
  <p>Here I noticed a difference between the Get Version (not working) and the Set version (working).</p>
  
  <p>Set sets the class <code>org.eclipse.jetty.server.handler.HandlerList</code>
  Get gets and add to the class <code>org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection</code>, which is described as</p>
  
  <blockquote>
    <p>Jetty Handler collection that calls only the handler (=context) that
    matches the request path after performing the substring based matching
    of requests path to registered aliases</p>
  </blockquote>
  
  <p>Could there be a problem regarding the aliases?</p>
  
  <p>EDIT 2:</p>
  
  <p>I tried digging into this, but I really can't get this to work. I do not know about the differences between the integration test and the regular karaf, but there must be an issue. To reproduce the issue, just take a fresh karaf (3.0.3) container, do <code>feature:install war</code> and add the snippet to the etc/jetty.xml so it looks like this and edit the path of the resourceBase so it matches a local path.</p>
  
  <pre><code>&lt;?xml version="1.0"?&gt;
  
  &lt;!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//
  DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd"&gt;
  
  &lt;Configure class="org.eclipse.jetty.server.Server"&gt;
  
      &lt;!-- =========================================================== --&gt;
      &lt;!-- Set connectors --&gt;
      &lt;!-- =========================================================== --&gt;
      &lt;!-- One of each type! --&gt;
      &lt;!-- =========================================================== --&gt;
  
      &lt;!-- Use this connector for many frequently idle connections and for 
          threadless continuations. --&gt;
      &lt;Call name="addConnector"&gt;
          &lt;Arg&gt;
              &lt;New class="org.eclipse.jetty.server.nio.SelectChannelConnector"&gt;
                  &lt;Set name="host"&gt;
                      &lt;Property name="jetty.host" /&gt;
                  &lt;/Set&gt;
                  &lt;Set name="port"&gt;
                      &lt;Property name="jetty.port" default="8181" /&gt;
                  &lt;/Set&gt;
                  &lt;Set name="maxIdleTime"&gt;300000&lt;/Set&gt;
                  &lt;Set name="Acceptors"&gt;2&lt;/Set&gt;
                  &lt;Set name="statsOn"&gt;false&lt;/Set&gt;
                  &lt;Set name="confidentialPort"&gt;8443&lt;/Set&gt;
                  &lt;Set name="lowResourcesConnections"&gt;20000&lt;/Set&gt;
                  &lt;Set name="lowResourcesMaxIdleTime"&gt;5000&lt;/Set&gt;
              &lt;/New&gt;
          &lt;/Arg&gt;
      &lt;/Call&gt;
  
      &lt;!-- =========================================================== --&gt;
      &lt;!-- Configure Authentication Realms --&gt;
      &lt;!-- Realms may be configured for the entire server here, or --&gt;
      &lt;!-- they can be configured for a specific web app in a context --&gt;
      &lt;!-- configuration (see $(jetty.home)/contexts/test.xml for an --&gt;
      &lt;!-- example). --&gt;
      &lt;!-- =========================================================== --&gt;
      &lt;Call name="addBean"&gt;
          &lt;Arg&gt;
              &lt;New class="org.eclipse.jetty.plus.jaas.JAASLoginService"&gt;
                  &lt;Set name="name"&gt;karaf&lt;/Set&gt;
                  &lt;Set name="loginModuleName"&gt;karaf&lt;/Set&gt;
                  &lt;Set name="roleClassNames"&gt;
                      &lt;Array type="java.lang.String"&gt;
                          &lt;Item&gt;org.apache.karaf.jaas.boot.principal.RolePrincipal
                          &lt;/Item&gt;
                      &lt;/Array&gt;
                  &lt;/Set&gt;
              &lt;/New&gt;
          &lt;/Arg&gt;
      &lt;/Call&gt;
      &lt;Call name="addBean"&gt;
          &lt;Arg&gt;
              &lt;New class="org.eclipse.jetty.plus.jaas.JAASLoginService"&gt;
                  &lt;Set name="name"&gt;default&lt;/Set&gt;
                  &lt;Set name="loginModuleName"&gt;karaf&lt;/Set&gt;
                  &lt;Set name="roleClassNames"&gt;
                      &lt;Array type="java.lang.String"&gt;
                          &lt;Item&gt;org.apache.karaf.jaas.boot.principal.RolePrincipal
                          &lt;/Item&gt;
                      &lt;/Array&gt;
                  &lt;/Set&gt;
              &lt;/New&gt;
          &lt;/Arg&gt;
      &lt;/Call&gt;
      &lt;Get name="handler"&gt;
      &lt;Call name="addHandler"&gt;
          &lt;Arg&gt;
              &lt;New class="org.eclipse.jetty.server.handler.ContextHandler"&gt;
                  &lt;Set name="contextPath"&gt;/static-content&lt;/Set&gt;
                  &lt;Set name="handler"&gt;
                      &lt;New class="org.eclipse.jetty.server.handler.ResourceHandler"&gt;
                          &lt;Set name="resourceBase"&gt;/Users/Shared/testenv/in&lt;/Set&gt;
                          &lt;Set name="directoriesListed"&gt;true&lt;/Set&gt;
                      &lt;/New&gt;
                  &lt;/Set&gt;
              &lt;/New&gt;
          &lt;/Arg&gt;
      &lt;/Call&gt;
  &lt;/Get&gt;
  
  &lt;/Configure&gt;
  </code></pre>
  
  <p>Try to access the context via browser using localhost:8181/static-content.</p>
  
  <p>Result is always 404 - Not found.</p>
  
  <p>We have tried this on multiple systems running linux and windows.</p>