4

I have a Spring beans definition file, as below

<bean id="jettyZk" class="org.eclipse.jetty.server.Server" init-method="start" destroy-method="stop">
    <!-- properties, threadPool, connectors -->

    <property name="handler">
        <bean class="org.eclipse.jetty.servlet.ServletContextHandler">
            <property name="eventListeners">
                <list>
                    <!-- my.ContextLoaderListener
                    * An ApplicationContextAware ContextLoaderListener that allows for using the current ApplicationContext,
                    * as determined by ApplicationContextAware, as the parent for the Root WebApplicationContext.
                    * 
                    * Also provides for specifying the contextConfigLocation of the Root WebApplicationContext, because
                    * Eclipse Jetty 7 ServletContextHandler does not expose a setInitParameters method.
                    -->
                    <bean class="my.ContextLoaderListener">
                        <property name="contextConfigLocation" value="/META-INF/spring/applicationContext-securityZk.xml"/>
                    </bean>
                    <!-- not sure if this is needed, disabled for now -->
                    <!-- <bean class="org.springframework.web.context.request.RequestContextListener"/> -->
                </list>
            </property>
            <property name="servletHandler">
                <bean class="org.eclipse.jetty.servlet.ServletHandler">
                    <property name="filters">
                        <list>
                            <bean class="org.eclipse.jetty.servlet.FilterHolder">
                                <property name="name" value="springSecurityFilterChain"/>
                                <property name="filter">
                                    <bean class="org.springframework.web.filter.DelegatingFilterProxy"/>
                                </property>
                            </bean>
                        </list>
                    </property>
                    <!-- filterMappings, servlets, servletMappings -->
                </bean>
            </property>
        </bean>
    </property>
</bean>

When trying to start the context, I get the following exception

Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: ServletContext must not be null

Caused by: java.lang.IllegalArgumentException: ServletContext must not be null
    at org.springframework.util.Assert.notNull(Assert.java:112)
    at org.springframework.web.context.support.WebApplicationContextUtils.getWebApplicationContext(WebApplicationContextUtils.java:109)

This is using Spring 3.0.5.RELEASE

The exception is understandable, looking at the code and JavaDocs for DelegatingFilterProxy#findWebApplicationContext, which says

The WebApplicationContext must have already been loaded and stored in the ServletContext before this filter gets initialized (or invoked).

because I'm trying to create the filter as a (sub)property of the context handler, so it seems sensible that the context has not yet been initialized and thus neither has the Spring WAC.

What I'd like to know is how can I configure Spring Security in an embedded Jetty container that Spring itself is assembling?

It seems like there's a catch 22 scenario that just needs a late initialisation, but I can't find a suitable flag to twiddle. I've tried setting lazy-init="true" onto the filter bean, but that didn't seem to achieve much, unsurprisingly.

Related: How to embed Jetty into Spring and make it use the same AppContext it was embedded into?

Community
  • 1
  • 1
ptomli
  • 11,730
  • 4
  • 40
  • 68
  • As a result of trying to deal with this I've been looking at Spring JavaConfig, and there's a related question: http://stackoverflow.com/questions/6683771/spring-configuration-and-contextcomponent-scan – ptomli Jul 13 '11 at 18:33
  • Did you ever figure out a way to do this? I have basically the same question. – tdimmig Apr 22 '13 at 18:20
  • I ended up with a @Configuration based setup – ptomli Apr 23 '13 at 08:51
  • I am dealing with similar problem can you point to any good source of information or example? – Rafael Jan 08 '14 at 15:55

1 Answers1

0

I am running Jetty 6.1.4 and Spring 3.0.5, but I am doing it the old fashioned way, with WEB-INF/web.xml.

With that approach, it's causing zero problems.

public class JettyServer {

    public static void main(String[] args) throws Exception {
    Properties props = new Properties();
    props.load(new FileInputStream("./etc/server.properties"));

    Server server = new Server();

    final String configFile = props.getProperty("server.config");

    XmlConfiguration configuration = 
        new XmlConfiguration(new File(configFile).toURI().toURL());
    configuration.configure(server);
    HandlerCollection handlers = new HandlerCollection();

    WebAppContext webapp = new WebAppContext();
    webapp.setContextPath(props.getProperty("context.path"));
    webapp.setDefaultsDescriptor(props.getProperty("default.config"));

    webapp.setWar(props.getProperty("war.path"));

    NCSARequestLog requestLog = new NCSARequestLog(props.getProperty("log.file"));
    requestLog.setExtended(true);
    RequestLogHandler requestLogHandler = new RequestLogHandler();
    requestLogHandler.setRequestLog(requestLog);

    handlers.setHandlers(
       new Handler[] { webapp, new DefaultHandler(), requestLogHandler });

    server.setHandler(handlers);

    server.setStopAtShutdown(true);
    server.setSendServerVersion(true);

    server.start();
    server.join();
}
Community
  • 1
  • 1
Andrei Taranchenko
  • 1,266
  • 1
  • 10
  • 22
  • You're having Jetty serve up a WAR file, which is not quite what I'm doing. *ponder* I've spent another few hours or so debugging how it's all called, and I don't have the `org.eclipse.jetty.webapp` package available at runtime, so it seems that regardless of where I get Spring to instantiated the filter, afterPropertiesSet gets called before my ServletContext is initialized. I did notice that I'm setting "filters" on the wrong container, so I'll update the sample in the question, but I'm still stuck. Thanks though :) – ptomli Jul 11 '11 at 20:37