jettysbtxsbt-web-pluginjetty-9

java.lang.reflect.InvocationTargetException in jetty-web.xml when setting WebAppContext.configurationClasses


I'm trying to add org.eclipse.jetty.annotations.AnnotationConfiguration to the configurationClasses property of org.eclipse.jetty.webapp.WebAppContext but (when invoking Jetty with sbt containe:start), getting:

[warn] Config error at <Set name="configurationClasses">
[warn]         <Array type="java.lang.String"><Item>org.eclipse.jetty.webapp.WebInfConfiguration</Item><Item>org.eclipse.jetty.webapp.WebXmlConfiguration</Item><Item>org.eclipse.jetty.webapp.MetaInfConfiguration</Item><Item>org.eclipse.jetty.webapp.FragmentConfiguration</Item><Item>org.eclipse.jetty.plus.webapp.EnvConfiguration</Item><Item>org.eclipse.jetty.plus.webapp.PlusConfiguration</Item><Item>org.eclipse.jetty.annotations.AnnotationConfiguration</Item><Item>org.eclipse.jetty.webapp.JettyWebXmlConfiguration</Item></Array>
[warn]     </Set>java.lang.reflect.InvocationTargetException in file:/Users/erik.allik/code/scala/webtest/src/main/webapp/WEB-INF/jetty-web.xml
[warn] Failed startup of context o.e.j.w.WebAppContext@33acb4a1{/,[file:/Users/erik.allik/code/scala/webtest/src/main/webapp/],STARTING}

I've tried changing the <Set ...> to a <Call name="setConfigurationClasses"> (with both the String[] as well as List<String> variants) to no avail—still getting the same reflection exception every time.

My jetty-web.xml is as follows:

<?xml version="1.0"  encoding="ISO-8859-1"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
    <Set name="configurationClasses">
        <Array type="java.lang.String">
            <Item>org.eclipse.jetty.webapp.WebInfConfiguration</Item>
            <Item>org.eclipse.jetty.webapp.WebXmlConfiguration</Item>
            <Item>org.eclipse.jetty.webapp.MetaInfConfiguration</Item>
            <Item>org.eclipse.jetty.webapp.FragmentConfiguration</Item>
            <Item>org.eclipse.jetty.plus.webapp.EnvConfiguration</Item>
            <Item>org.eclipse.jetty.plus.webapp.PlusConfiguration</Item>
            <Item>org.eclipse.jetty.annotations.AnnotationConfiguration</Item>
            <Item>org.eclipse.jetty.webapp.JettyWebXmlConfiguration</Item>
        </Array>
    </Set>
</Configure>

ANSWER: deciding by https://github.com/JamesEarlDouglas/xsbt-web-plugin/blob/master/src/jetty-9/scala/Jetty9Runner.scala, xsbt-web-plugin sets the configurations property of WebAppContext to a hardcoded value, so no matter what's in the XML configs, it probably simply gets ignored (or causes an error, apparently).


Solution

  • The Configuration classes exist to configure the WebAppContext itself.

    Adding the Configurations in the jetty-web.xml or the Jetty IoC XML Context Deployable is too late in the lifecycle.

    If you look at etc/jetty-annotations.xml you'll see ...

    <?xml version="1.0"?>
    <!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
    
    <Configure id="Server" class="org.eclipse.jetty.server.Server">
      <!-- =========================================================== -->
      <!-- Add annotation Configuring classes to all webapps for this Server -->
      <!-- =========================================================== -->
      <Call class="org.eclipse.jetty.webapp.Configuration$ClassList" name="setServerDefault">
        <Arg><Ref refid="Server" /></Arg>
        <Call name="addBefore">
          <Arg name="beforeClass">org.eclipse.jetty.webapp.JettyWebXmlConfiguration</Arg>
          <Arg>
            <Array type="String">
              <Item>org.eclipse.jetty.annotations.AnnotationConfiguration</Item>
            </Array>
          </Arg>
        </Call>
      </Call>
    </Configure>
    

    and etc/jetty-plus.xml you'll see ...

    <?xml version="1.0"?>
    <!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
    
    <!-- =============================================================== -->
    <!-- Configure extended support for webapps                          -->
    <!-- =============================================================== -->
    <Configure id="Server" class="org.eclipse.jetty.server.Server">
    
      <!-- =========================================================== -->
      <!-- Add plus Configuring classes to all webapps for this Server -->
      <!-- =========================================================== -->
      <Call class="org.eclipse.jetty.webapp.Configuration$ClassList" name="setServerDefault">
        <Arg><Ref refid="Server" /></Arg>
        <Call name="addAfter">
          <Arg name="afterClass">org.eclipse.jetty.webapp.FragmentConfiguration</Arg>
          <Arg>
            <Array type="String">
              <Item>org.eclipse.jetty.plus.webapp.EnvConfiguration</Item>
              <Item>org.eclipse.jetty.plus.webapp.PlusConfiguration</Item>
            </Array>
          </Arg>
        </Call>
      </Call>
    </Configure>
    

    If you notice, you'll see that these are configured at the server level, and are based on existing defaults (to satisfy ordering requirements of the Configurations).