0

I am using embedded jetty and loading contexts through xml file. In my application, following contexts were deployed in my jetty 6.1.7 version:

    <New class="org.mortbay.jetty.servlet.Context">
        <Arg>
            <Ref id="Contexts"/>
        </Arg>
        <Arg>/cts</Arg>
        <Set name="resourceBase">
            <SystemProperty name="jetty.home" default="."/>/</Set>
        <Set name="sessionHandler">
            <New class="org.mortbay.jetty.servlet.SessionHandler"/>
        </Set>
        <Call name="addServlet">
            <Arg>com.docu.cts.webservices.remote.TransformationServlet</Arg>
            <Arg>/</Arg>
        </Call>
    </New>
    <New class="org.mortbay.jetty.servlet.Context">
        <Arg>
            <Ref id="Contexts"/>
        </Arg>
        <Arg>/cts/monitor</Arg>
        <Set name="resourceBase">
            <SystemProperty name="jetty.home" default="."/>/</Set>
        <Set name="sessionHandler">
            <New class="org.mortbay.jetty.servlet.SessionHandler"/>
        </Set>
        <Call name="addServlet">
            <Arg>com.docu.cts.webservices.remote.MonitorServlet</Arg>
            <Arg>/</Arg>
        </Call>
    </New>
    <New class="org.mortbay.jetty.servlet.Context">
        <Arg>
            <Ref id="Contexts"/>
        </Arg>
        <Arg>/cts/blazon</Arg>
        <Set name="resourceBase">
            <SystemProperty name="jetty.home" default="."/>/</Set>
        <Set name="sessionHandler">
            <New class="org.mortbay.jetty.servlet.SessionHandler"/>
        </Set>
        <Call name="addServlet">
            <Arg>com.docu.cts.webservices.remote.BlazonJobServlet</Arg>
            <Arg>/</Arg>
        </Call>
    </New>  
    <New class="org.mortbay.jetty.servlet.Context">
        <Arg>
            <Ref id="Contexts"/>
        </Arg>
        <Arg>/cts/getCapabilities</Arg>
        <Set name="resourceBase">
            <SystemProperty name="jetty.home" default="."/>/</Set>
        <Set name="sessionHandler">
            <New class="org.mortbay.jetty.servlet.SessionHandler"/>
        </Set>
        <Call name="addServlet">
            <Arg>com.docu.cts.webservices.remote.CapabilityServlet</Arg>
            <Arg>/</Arg>
        </Call>
    </New>
    <New class="org.mortbay.jetty.servlet.Context">
        <Arg>
            <Ref id="Contexts"/>
        </Arg>
        <Arg>/cts/output</Arg>
        <Set name="resourceBase">
            <SystemProperty name="jetty.home" default="."/>/../cache/</Set>
        <Call name="addServlet">
            <Arg>com.docu.cts.webservices.remote.FileProxyServlet</Arg>
            <Arg>/</Arg>
        </Call>
    </New>
    <New class="org.mortbay.jetty.servlet.Context">
        <Arg>
            <Ref id="Contexts"/>
        </Arg>
        <Arg>/cts/resource</Arg>
        <Set name="resourceBase">
            <SystemProperty name="jetty.home" default="."/>/../resource/</Set>
        <Call name="addServlet">
            <Arg>com.docu.cts.webservices.remote.FileProxyServlet</Arg>
            <Arg>/</Arg>
        </Call>
    </New>
    <New class="org.mortbay.jetty.servlet.Context">
        <Arg>
            <Ref id="Contexts"/>
        </Arg>
        <Arg>/cts/canExecute</Arg>
        <Set name="resourceBase">
            <SystemProperty name="jetty.home" default="."/>/</Set>
        <Set name="sessionHandler">
            <New class="org.mortbay.jetty.servlet.SessionHandler"/>
        </Set>
        <Call name="addServlet">
            <Arg>com.docu.cts.webservices.remote.CanExecuteServlet</Arg>
            <Arg>/</Arg>
        </Call>
    </New>
    <New class="org.mortbay.jetty.servlet.Context">
        <Arg>
            <Ref id="Contexts"/>
        </Arg>
        <Arg>/cts/getOccupancy</Arg>
        <Set name="resourceBase">
            <SystemProperty name="jetty.home" default="."/>/</Set>
        <Set name="sessionHandler">
            <New class="org.mortbay.jetty.servlet.SessionHandler"/>
        </Set>
        <Call name="addServlet">
            <Arg>com.docu.cts.webservices.remote.GetOccupancyServlet</Arg>
            <Arg>/</Arg>
        </Call>
    </New>
    <New class="org.mortbay.jetty.servlet.Context">
        <Arg>
            <Ref id="Contexts"/>
        </Arg>
        <Arg>/cts/delete</Arg>
        <Set name="resourceBase">
            <SystemProperty name="jetty.home" default="."/>/</Set>
        <Set name="sessionHandler">
            <New class="org.mortbay.jetty.servlet.SessionHandler"/>
        </Set>
        <Call name="addServlet">
            <Arg>com.docu.cts.webservices.remote.CleanupJobServlet</Arg>
            <Arg>/</Arg>
        </Call>
    </New>

We are moving to jetty 9 and and tried deploying contexts something like this:

<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<Configure id="Contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection">
    <New class="org.eclipse.jetty.servlet.ServletContextHandler">
        <Arg>
            <Ref id="Contexts"/>
        </Arg>
        <Arg>/cts</Arg>
        <Set name="resourceBase">
            <SystemProperty name="jetty.base" default="."/>/</Set>
        <Set name="sessionHandler">
            <New class="org.eclipse.jetty.server.session.SessionHandler"/>
        </Set>
        <Call name="addServlet">
            <Arg>com.docu.cts.webservices.remote.TransformationServlet</Arg>
            <Arg>/</Arg>
        </Call>
    </New>
    <New class="org.eclipse.jetty.servlet.ServletContextHandler">
        <Arg>
            <Ref id="Contexts"/>
        </Arg>
        <Arg>/cts/monitor</Arg>
        <Set name="resourceBase">
            <SystemProperty name="jetty.base" default="."/>/</Set>
        <Set name="sessionHandler">
            <New class="org.eclipse.jetty.server.session.SessionHandler"/>
        </Set>
        <Call name="addServlet">
            <Arg>com.docu.cts.webservices.remote.MonitorServlet</Arg>
            <Arg>/</Arg>
        </Call>
    </New>
    <New class="org.eclipse.jetty.servlet.ServletContextHandler">
        <Arg>
            <Ref id="Contexts"/>
        </Arg>
        <Arg>/cts/blazon</Arg>
        <Set name="resourceBase">
            <SystemProperty name="jetty.base" default="."/>/</Set>
        <Set name="sessionHandler">
            <New class="org.eclipse.jetty.server.session.SessionHandler"/>
        </Set>
        <Call name="addServlet">
            <Arg>com.docu.cts.webservices.remote.BlazonJobServlet</Arg>
            <Arg>/</Arg>
        </Call>
    </New>  
    <New class="org.eclipse.jetty.servlet.ServletContextHandler">
        <Arg>
            <Ref id="Contexts"/>
        </Arg>
        <Arg>/cts/getCapabilities</Arg>
        <Set name="resourceBase">
            <SystemProperty name="jetty.base" default="."/>/</Set>
        <Set name="sessionHandler">
            <New class="org.eclipse.jetty.server.session.SessionHandler"/>
        </Set>
        <Call name="addServlet">
            <Arg>com.docu.cts.webservices.remote.CapabilityServlet</Arg>
            <Arg>/</Arg>
        </Call>
    </New>
    <New class="org.eclipse.jetty.servlet.ServletContextHandler">
        <Arg>
            <Ref id="Contexts"/>
        </Arg>
        <Arg>/cts/output</Arg>
        <Set name="resourceBase">
            <SystemProperty name="jetty.base" default="."/>/../cache/</Set>
        <Call name="addServlet">
            <Arg>com.docu.cts.webservices.remote.FileProxyServlet</Arg>
            <Arg>/</Arg>
        </Call>
    </New>
    <New class="org.eclipse.jetty.servlet.ServletContextHandler">
        <Arg>
            <Ref id="Contexts"/>
        </Arg>
        <Arg>/cts/resource</Arg>
        <Set name="resourceBase">
            <SystemProperty name="jetty.base" default="."/>/../resource/</Set>
        <Call name="addServlet">
            <Arg>com.docu.cts.webservices.remote.FileProxyServlet</Arg>
            <Arg>/</Arg>
        </Call>
    </New>
    <New class="org.eclipse.jetty.servlet.ServletContextHandler">
        <Arg>
            <Ref id="Contexts"/>
        </Arg>
        <Arg>/cts/canExecute</Arg>
        <Set name="resourceBase">
            <SystemProperty name="jetty.base" default="."/>/</Set>
        <Set name="sessionHandler">
            <New class="org.eclipse.jetty.server.session.SessionHandler"/>
        </Set>
        <Call name="addServlet">
            <Arg>com.docu.cts.webservices.remote.CanExecuteServlet</Arg>
            <Arg>/</Arg>
        </Call>
    </New>
    <New class="org.eclipse.jetty.servlet.ServletContextHandler">
        <Arg>
            <Ref id="Contexts"/>
        </Arg>
        <Arg>/cts/getOccupancy</Arg>
        <Set name="resourceBase">
            <SystemProperty name="jetty.base" default="."/>/</Set>
        <Set name="sessionHandler">
            <New class="org.eclipse.jetty.server.session.SessionHandler"/>
        </Set>
        <Call name="addServlet">
            <Arg>com.docu.cts.webservices.remote.GetOccupancyServlet</Arg>
            <Arg>/</Arg>
        </Call>
    </New>
    <New class="org.eclipse.jetty.servlet.ServletContextHandler">
        <Arg>
            <Ref id="Contexts"/>
        </Arg>
        <Arg>/cts/delete</Arg>
        <Set name="resourceBase">
            <SystemProperty name="jetty.base" default="."/>/</Set>
        <Set name="sessionHandler">
            <New class="org.eclipse.jetty.server.session.SessionHandler"/>
        </Set>
        <Call name="addServlet">
            <Arg>com.docu.cts.webservices.remote.CleanupJobServlet</Arg>
            <Arg>/</Arg>
        </Call>
    </New>
</Configure> 

basically I have used latest APIs of jetty thats it, I am not sure if this is the correct way of deploying contexts or not. Any inputs provided will be really helpful.

Avinash Modi
  • 81
  • 2
  • 8

1 Answers1

1

All of these details were covered in my prior answer to you at How to enable embedded jetty 9 in SSL mode through xml configuration? (including a link to an example project that does exactly what you asked there and here)

Don't use the ServletContextHandler constructor technique (aka <Arg> elements) when doing things with contexts and XML (those techniques are reserved for implementations of AppProvider from the DeploymentManager, which you are obviously not using).

Your Jetty 9 XML is setup to configure the id of Contexts (which is of class org.eclipse.jetty.server.handler.ContextHandlerCollection).

Then it creates a bunch of ServletContextHandler objects (the <New> elements), and doesn't add them to anywhere. Again, don't use the Constructor techniques.

What you have are orphaned contexts that don't belong anywhere, and Jetty is unaware of them.

You have a few things to fix.

  1. Remove your <Arg> element inside the first level of <New class="org.eclipse.jetty.servlet.ServletContextHandler">, all of them.
  2. Add appropriate <Set name="contextPath">/cts</Set> for each ServletContextHandler (be sure not to overlap or cause conflicts across your chosen contexts, like you currently have)
  3. Use the Servlet url-pattern appropriately. If you use the url-pattern of / that's the "default" pattern, and that means your resourceBase is super important and your have to satisfy the rules of the "Default Servlet" in your servlet implementations.
  4. Use a single ServletContextHandler to avoid having separate HttpSession objects / trees / storage for each and every context (this is enforced by Jetty and the Servlet Spec and cannot be overridden). For example: your /cts/delete context cannot set / see / use the HttpSession from /cts and vice-versa.
  5. Finally add the resulting ServletContextHandler to the ContextHandlerCollection.

Taking all of the advice together, smashing this into a single ServletContextHandler (to avoid issues with ResourceBase and HttpSession) you have the following result:

<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<Configure id="Contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection">
  <Call name="addHandler">
    <Arg>
      <New class="org.eclipse.jetty.servlet.ServletContextHandler">
        <Set name="contextPath">/cts</Set>
        <!-- it would be smarter to have a `base` dir with `/resource` and `/output` sub directories, to avoid having to redeclare the locations in your specific servlets) -->
        <Set name="resourceBase"><SystemProperty name="jetty.base" default="."/>/</Set>
        <!-- This is incomplete, like you have it, so I left it incomplete.
             Your HTTP Sessions will likely not behave like you expect
             if you leave it like this -->
        <Set name="sessionHandler">
          <New class="org.eclipse.jetty.server.session.SessionHandler"/>
        </Set>
        <!-- Use url-pattern properly, not separate Contexts! -->
        <Call name="addServlet">
          <Arg>com.docu.cts.webservices.remote.TransformationServlet</Arg>
          <Arg>/</Arg>
        </Call>
        <Call name="addServlet">
          <Arg>com.docu.cts.webservices.remote.MonitorServlet</Arg>
          <Arg>/monitor</Arg>
        </Call>
        <Call name="addServlet">
          <Arg>com.docu.cts.webservices.remote.BlazonJobServlet</Arg>
          <Arg>/blazon</Arg>
        </Call>
        <Call name="addServlet">
          <Arg>com.docu.cts.webservices.remote.CapabilityServlet</Arg>
          <Arg>/getCapabilities</Arg>
        </Call>
        <Call name="addServlet">
          <Arg>com.docu.cts.webservices.remote.CanExecuteServlet</Arg>
          <Arg>/canExecute</Arg>
        </Call>
        <Call name="addServlet">
          <Arg>com.docu.cts.webservices.remote.GetOccupancyServlet</Arg>
          <Arg>/getOccupancy</Arg>
        </Call>
        <Call name="addServlet">
          <Arg>com.docu.cts.webservices.remote.CleanupJobServlet</Arg>
          <Arg>/delete</Arg>
        </Call>
        <!-- The location of the content needs to be passed in as it doesn't fit within the base resource cleanly.
             Easily fixed by having a sane directory structure for your resource base you pass into the servlet context handler instead. -->
        <Call name="addServlet">
          <Arg>com.docu.cts.webservices.remote.FileProxyServlet</Arg>
          <Arg>/output</Arg>
          <Call name="setInitParameter">
            <Arg>fileContentBase</Arg>
            <Arg><SystemProperty name="jetty.base" default="."/>/../cache/</Arg>
          </Call>
        </Call>
        <!-- The location of the content needs to be passed in as it doesn't fit within the base resource cleanly.
             Easily fixed by having a sane directory structure for your resource base you pass into the servlet context handler instead. -->
        <Call name="addServlet">
          <Arg>com.docu.cts.webservices.remote.FileProxyServlet</Arg>
          <Arg>/resource</Arg>
          <Call name="setInitParameter">
            <Arg>fileContentBase</Arg>
            <Arg><SystemProperty name="jetty.base" default="."/>/../resource/</Arg>
          </Call>
        </Call>
      </New>
    </Arg>
  </Call>
</Configure>
Joakim Erdfelt
  • 46,896
  • 7
  • 86
  • 136