views:

539

answers:

1

Hi StackOverflow!

My application requires several interface implementations which require a Jetty server to do their job. This is, however, not necessarily the case in every implementations of those interfaces so the Jetty server is only a dependency.

Since it would be a huge amount of pain to wrap the entire jetty server with all its logging, connector and Handler configurations, I want to inject the server to those implementations with Spring. I decided that injecting the Server class is not a good idea because an implementation could stop the server even if its required at another location. Currently I inject empty HandlerList classes to those implementations and they register their handlers to avoid those problems.

The Problem: Those handlers might interfere with other handlers for example: implementation one might register a handler for /foo and implementation two too... problem. Has anyone used Jetty in such an environment? And how could this problem be solved?

My XML to clarify my problem:

<bean id="jetty" class="org.eclipse.jetty.server.Server" destroy-method="stop">
    <property name="connectors">
        <list>
            <bean class="org.eclipse.jetty.server.bio.SocketConnector">
                <property name="host" value="10.8.0.46" />
                <property name="port" value="9999" />
            </bean>
        </list>
    </property>

    <property name="handler">
        <bean class="org.eclipse.jetty.server.handler.HandlerCollection">
            <property name="handlers">
                <list>
                    <ref bean="jetty.handlerList" />
                    <bean class="org.eclipse.jetty.server.handler.RequestLogHandler">
                        <property name="requestLog">
                            <bean class="org.eclipse.jetty.server.NCSARequestLog">
                                <constructor-arg value="${jetty.logfile}" />
                                <property name="extended" value="false"/>
                            </bean>
                        </property>
                    </bean>
                </list>
            </property>
        </bean>
    </property>

    <property name="sendServerVersion" value="false" />
</bean>

<bean id="jetty.handlerList" class="org.eclipse.jetty.server.handler.HandlerList" />

If I require an empty HandlerList I use something like this where com.example.myapp.util.ioc.CreateHandlerListFactory is a org.springframework.beans.factory.FactoryBean which creates a new HandlerList within the given HandlerList.

<constructor-arg>
    <bean class="com.example.myapp.util.ioc.CreateHandlerListFactory">
        <constructor-arg ref="jetty.handlerList"/>
    </bean>
</constructor-arg>
A: 

I have a few possible suggestions:

Add an org.eclipse.jetty.servlet.ServletHandler and instead of Jetty-specific Handlers, map standard Servlets instead. You can set the ServletHandler's Servlets either by adding them one-by-one (each wrapped in a ServletHolder) or with setServlets(ServletHolder[] holders). The ServletMappings are set similarly.

You could inject the ServletHandler to each interface implementation to let them add their mapped servlets, or centrally create arrays of ServletHolders and ServletMappings, thereby also preventing duplicated paths by keeping control of the paths out of each interface implementation. The latter would also allow at least the interface implementations to be programmed against the standard Servlet API, making the bulk of your code independent of Jetty.

Stefan L