spring-projects / spring-framework

Spring Framework
https://spring.io/projects/spring-framework
Apache License 2.0
55.48k stars 37.71k forks source link

Unable to use Lazy loaded collections in servlet 2.2 container without filter support [SPR-350] #5080

Closed spring-projects-issues closed 19 years ago

spring-projects-issues commented 19 years ago

Keith Garry Boyce opened SPR-350 and commented

Unable to use Lazy loaded collections in servlet 2.2 container without filter support. This needs to be addressed in a different way for servlet 2.2 containers


Affects: 1.1 final

Attachments:

spring-projects-issues commented 19 years ago

Juergen Hoeller commented

I'm aware that OpenSessionInViewFilter does not work on Servlet 2.2 containers, of course. Your only out-of-the-box choice on such a container is OpenSessionInViewInterceptor for Spring's own web MVC framework. This will obviously not work with a different web framework like Struts 1.1, though.

As Servlet 2.2 simply does not offer a facility to hook into the request processing lifecycle, we cannot provide a standard solution there. The only thing you can do on such a container is to use an interceptor for the web framework of your choice: Besides Spring's own web MVC, WebWork is known to have good facilities in that area.

Unfortunately, Struts does not provide nice interceptor hooks out-of-the-box. You could possibly achieve something similar via a custom RequestProcessor subclass that intercepts request processing, but this might be in conflict with other RequestProcessor subclasses that you already use. You could try to provide your own combination here.

We do not plan to provide such Open Session in View support other than via our current classes for Servlet 2.3 and Spring's web MVC. The current Servlet API version is already 2.4, and we do provide a standard solution that works with any web framework for Servlet API >= 2.3. And Servlet 2.2 containers are not very common anymore...

Juergen

spring-projects-issues commented 19 years ago

Keith Garry Boyce commented

Is it possible to use OpenSessionInViewInterceptor with SimpleUrlHandlerMapping delegating to struts controller. If so please send an example of this.

spring-projects-issues commented 19 years ago

Keith Garry Boyce commented

See link http://forum.springframework.org/viewtopic.php?t=994

I am hoping that they will include this in the next Spring release and [b]give me some credit[/b]. It appears to work really well. I developed this because I am on a servlet 2.2 container and so I can't use the openSessionInViewFilter. The code below will allow you to run all your struts stuff through spring giving you the advantage of wiring etc. :) . [b]The instructions are in the Javadoc included in the code.[/b] [code] /*

*/ package org.springframework.web.struts;

import java.util.Enumeration; import java.util.Hashtable; import java.util.Map;

import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionServlet; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.ApplicationContextAware; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.AbstractController;

/**

\

\

\

\

\

\

*

\

\

*

\

\



<bean id="strutsController"

class="org.springframework.web.struts.StrutsController"

singleton="true">

<property name="initParameters">

<map>

<entry key="config">

<value>/WEB-INF/struts-config.xml</value>

</entry>

</map>

</property>

</bean>


<bean id="handlerMapping"

class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">

<property name="interceptors">

<list>

<ref bean="openSessionInViewInterceptor"/>

</list>

</property>

<property name="urlMap">

<map>
*
<entry key="/*"><ref bean="strutsController"/></entry>

</map>

</property>

</bean>


\

\

*

*/ public class StrutsController extends AbstractController implements ApplicationContextAware, InitializingBean { private ActionServlet actionServlet;

private Map initParameters;

/*
 * (non-Javadoc)
 * 
 * @see org.springframework.web.servlet.mvc.AbstractController#handleRequestInternal(javax.servlet.http.HttpServletRequest,
 *      javax.servlet.http.HttpServletResponse)
 */
protected ModelAndView handleRequestInternal(HttpServletRequest request,
        HttpServletResponse response) throws Exception {
    actionServlet.doGet(request, response);
    return null;
}

/*
 * (non-Javadoc)
 * 
 * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
 */
public void afterPropertiesSet() throws Exception {
    actionServlet = new ActionServlet();

    ServletConfig servletConfig = new MyServletConfig();
    actionServlet.init(servletConfig);
    getWebApplicationContext().getServletContext().setAttribute(
            WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,
            getWebApplicationContext());
}

/**
 * Sets servlet initialization parameters for ActionServlet
 * 
 * @param initParameters
 *            The initParameters to set.
 */
public final void setInitParameters(Map initParameters) {
    this.initParameters = initParameters;
}

private class MyServletConfig implements ServletConfig {

    /*
     * (non-Javadoc)
     * 
     * @see javax.servlet.ServletConfig#getInitParameter(java.lang.String)
     */
    public String getInitParameter(String configParameter) {
        return (String) initParameters.get(configParameter);
    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.servlet.ServletConfig#getInitParameterNames()
     */
    public Enumeration getInitParameterNames() {
        return new Hashtable(initParameters).keys();
    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.servlet.ServletConfig#getServletContext()
     */
    public ServletContext getServletContext() {
        return getWebApplicationContext().getServletContext();
    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.servlet.ServletConfig#getServletName()
     */
    public String getServletName() {
        return this.getClass().getName();
    }

}

} [/code]

spring-projects-issues commented 19 years ago

Juergen Hoeller commented

Actually, there's an easier solution: I've just implemented a ServletWrappingController that simply delegates to a named servlet - within Spring's dispatching infrastructure! I.e. you define a controller like the following:

\ \\action\\ \

and map it via a SimpleUrlHandlerMapping, you're able to link in any Spring HandlerInterceptors (e.g. OpenSessionInViewInterceptor), while forwarding all requests to the specified servlet.

The "servletName" simply has to match the "servlet-name" in web.xml. Note that you don't even need a "servlet-mapping" for that servlet there; a plain "servlet" definition is enough.

The advantage of the above solution over your prototype is that the Struts ActionServlet is still completely managed by the servlet container; no need to emulate ServletConfig etc. Essentially, Spring just replaces the "servlet-mapping" in such a scenario.

I'll include the above in Spring 1.1.1, as it is pretty trivial and completely independent from both Struts and Hibernate, but still can serve to apply OpenSessionInViewInterceptor to Struts actions in a Servlet 2.2 environment!

I've never thought about applying Spring's dispatching infrastructure that way, so thanks for your suggestion :-) If you have the chance, please give the ServletWrappingController a try, once it is visible in public CVS!

Juergen

spring-projects-issues commented 19 years ago

Keith Garry Boyce commented

Sounds good to me. I hope I still get some credit in the Javadoc for coming up with the idea. Thanks.... Can you send the code to me so I can use it now. My email is keithgarry.boyce (at) bcbsma.com. Thanks, Garry

spring-projects-issues commented 19 years ago

Keith Garry Boyce commented

Also while we're at it do you think there is any way to include an action similar to ActionSupport which at construction time looks for the action in the webapplicationcontext and on finding the action calls the inversion of control setters eliminating the need for factory pattern to do the setting??? I know that the setters themselves can't be called until construction is complete be by using reflection isn't it possible to set the variables themselves even on private members by setting the variable to be accessible.

spring-projects-issues commented 19 years ago

Keith Garry Boyce commented

One other thing. It is essential that the servlet being mapped should think it has the same name as the dispatcher servlet so that the mappings associated with the dispatcher servlet are inherited by it. Struts will not work otherwise. In my source I made a change to assign the servlet name to to servletconfig assigned to action servlet like

web.xml \ \controllerServlet\ \org.springframework.web.servlet.DispatcherServlet\ \ \contextConfigLocation\ \/WEB-INF/applicationContext.xml\ \

    <load-on-startup>2</load-on-startup>
</servlet>

applicationContext.xml \<bean id="strutsController" class="org.springframework.web.struts.StrutsController" singleton="true"> \ \ \ \/WEB-INF/struts-config.xml\ \ \ \ \ \controllerServlet\ \ \

You may have a better way to do it

spring-projects-issues commented 19 years ago

Keith Garry Boyce commented

On researching how I would make your RequestDispatcher solution work I could not find a way to change the servlets perceived name as it was processing so when struts parsed the web.xml file looking for a servlet mapping it had a problem.

According to the doc: If the same url-pattern appears more than once within a web.xml file, the container makes no guarantees about which servlet receives a request

Since we would have got to struts through the dispatcher servlet then by definition we had a match there so it would not be kosher to put another servlet-mapping for in web.xml with the same mapping.

BTW I couldn't find a way to set the servletName automatically from the DispatchServlet otherwise I would have done so. That means that there is some Aware interface that should be implemented that is not. I would think if there was such a handler the handler would set that up in the controller.

In light of all this I changed my code as below.

/*

*/ package org.springframework.web.struts;

import java.util.Enumeration; import java.util.Hashtable; import java.util.Map;

import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils; import org.apache.struts.action.ActionServlet; import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.ApplicationContextAware; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.AbstractController;

/**

\

\

\

\

\

\

*

\

\

*

\

\



<bean id="strutsController"

class="org.springframework.web.struts.StrutsController"

singleton="true">

<property name="initParameters">

<map>

<entry key="config">

<value>/WEB-INF/struts-config.xml</value>

</entry>

</map>

</property>

</bean>


<bean id="handlerMapping"

class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">

<property name="interceptors">

<list>

<ref bean="openSessionInViewInterceptor"/>

</list>

</property>

<property name="urlMap">

<map>
*
<entry key="/*"><ref bean="strutsController"/></entry>

</map>

</property>

</bean>


\

\

*

*/ public class StrutsController extends AbstractController implements ApplicationContextAware, InitializingBean, BeanNameAware {

private ActionServlet actionServlet;

private Map initParameters;

private String controllerServletName;

private String beanName;

/*
 * (non-Javadoc)
 * 
 * @see org.springframework.web.servlet.mvc.AbstractController#handleRequestInternal(javax.servlet.http.HttpServletRequest,
 *      javax.servlet.http.HttpServletResponse)
 */
protected ModelAndView handleRequestInternal(HttpServletRequest request,
        HttpServletResponse response) throws Exception {
    actionServlet.doGet(request, response);
    return null;
}

/*
 * (non-Javadoc)
 * 
 * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
 */
public void afterPropertiesSet() throws Exception {

    actionServlet = new ActionServlet();

    ServletConfig servletConfig = new MyServletConfig();
    actionServlet.init(servletConfig);
    getWebApplicationContext().getServletContext().setAttribute(
            WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,
            getWebApplicationContext());
}

/**
 * Sets servlet initialization parameters for ActionServlet
 * 
 * @param initParameters
 *            The initParameters to set.
 */
public final void setInitParameters(Map initParameters) {
    this.initParameters = initParameters;
}

/**
 * @param servletName The servletName to set.
 */
public void setServletName(String servletName) {
    this.controllerServletName = servletName;
}

/* (non-Javadoc)
 * @see org.springframework.beans.factory.BeanNameAware#setBeanName(java.lang.String)
 */
public void setBeanName(String beanName) {
    this.beanName = beanName;        
}

private class MyServletConfig implements ServletConfig {

    /*
     * (non-Javadoc)
     * 
     * @see javax.servlet.ServletConfig#getInitParameter(java.lang.String)
     */
    public String getInitParameter(String configParameter) {
        return (String) initParameters.get(configParameter);
    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.servlet.ServletConfig#getInitParameterNames()
     */
    public Enumeration getInitParameterNames() {
        return new Hashtable(initParameters).keys();
    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.servlet.ServletConfig#getServletContext()
     */
    public ServletContext getServletContext() {
        return getWebApplicationContext().getServletContext();
    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.servlet.ServletConfig#getServletName()
     */
    public String getServletName() {
        return StringUtils.defaultString(controllerServletName,beanName);
    }

}

}

spring-projects-issues commented 19 years ago

Keith Garry Boyce commented

Refactored to be generic for all servlets while still allowing name to be defined. Here is wiring and below is code. Note package name and class name change.

<bean id="strutsController"
      class="org.springframework.web.servlet.mvc.ServletWrappingController"
      singleton="true">
    <property name="servletClass">
           <bean 
                class="org.apache.struts.action.ActionServlet"/>
    </property>
    <property name="servletName">
           <value>controllerServlet</value>
    </property>
    <property name="initParameters">
        <map>
            <entry key="config">
                <value>/WEB-INF/struts-config.xml</value>
            </entry>
        </map>
    </property>
</bean>

\ \ \ \ \ \ \ \ \\\ \ \ \ /*

*/ package org.springframework.web.servlet.mvc;

import java.util.Enumeration; import java.util.Hashtable; import java.util.Map;

import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.ApplicationContextAware; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.AbstractController;

/**

\

\

\

\

\

\

*

\

\

*

\

\


  • <bean id="strutsController"

class="org.springframework.web.servlet.mvc.ServletWrappingController" singleton="true"> <property name="servletClass"> <bean class="org.apache.struts.action.ActionServlet"/> </property> <property name="servletName"> <value>controllerServlet</value> </property> <property name="initParameters"> <map> <entry key="config"> <value>/WEB-INF/struts-config.xml</value> </entry> </map> </property> </bean> <bean id="handlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="interceptors"> <list> <ref bean="openSessionInViewInterceptor"/> </list> </property> <property name="urlMap"> <map> * <entry key="/*"><ref bean="strutsController"/></entry> </map> </property> </bean> \

*

\

*

*/ public class ServletWrappingController extends AbstractController implements ApplicationContextAware, InitializingBean, BeanNameAware {

private HttpServlet servletClass;

private Map initParameters;

private String controllerServletName;

private String beanName;

/*
 * (non-Javadoc)
 * 
 * @see org.springframework.web.servlet.mvc.AbstractController#handleRequestInternal(javax.servlet.http.HttpServletRequest,
 *      javax.servlet.http.HttpServletResponse)
 */
protected ModelAndView handleRequestInternal(HttpServletRequest request,
        HttpServletResponse response) throws Exception {
    servletClass.service(request, response);
    return null;
}

/*
 * (non-Javadoc)
 * 
 * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
 */
public void afterPropertiesSet() throws Exception {

    ServletConfig servletConfig = new MyServletConfig();
    servletClass.init(servletConfig);
    getWebApplicationContext().getServletContext().setAttribute(
            WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,
            getWebApplicationContext());
}

/**
 * Sets servlet initialization parameters for servlet
 * 
 * @param initParameters
 *            The initParameters to set.
 */
public final void setInitParameters(Map initParameters) {
    this.initParameters = initParameters;
}

/**
 * @param servletName The servletName to set.
 */
public void setServletName(String servletName) {
    this.controllerServletName = servletName;
}

/**
 * @param servlet The servlet to set.
 */
public void setServletClass(HttpServlet servletClass) {
    this.servletClass = servletClass;
}

/* (non-Javadoc)
 * @see org.springframework.beans.factory.BeanNameAware#setBeanName(java.lang.String)
 */
public void setBeanName(String beanName) {
    this.beanName = beanName;        
}

private class MyServletConfig implements ServletConfig {

    /*
     * (non-Javadoc)
     * 
     * @see javax.servlet.ServletConfig#getInitParameter(java.lang.String)
     */
    public String getInitParameter(String configParameter) {
        return (String) initParameters.get(configParameter);
    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.servlet.ServletConfig#getInitParameterNames()
     */
    public Enumeration getInitParameterNames() {
        return new Hashtable(initParameters).keys();
    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.servlet.ServletConfig#getServletContext()
     */
    public ServletContext getServletContext() {
        return getWebApplicationContext().getServletContext();
    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.servlet.ServletConfig#getServletName()
     */
    public String getServletName() {
        return StringUtils.defaultString(controllerServletName,beanName);
    }

}

}

spring-projects-issues commented 19 years ago

Juergen Hoeller commented

I've attached the ServletWrappingController.java file that I've just committed to CVS (to be part of Spring 1.1.1).

Note that your latest refactorings still hold the actual servlet instance within the controller. In contrast to that, ServletWrappingController refers to the servlet by name and forwards to it. The servlet itself is managed by the servlet container, defined via a \ declaration in web.xml (as usual). Have a look at ServletWrappingController's javadoc for an example.

Juergen

spring-projects-issues commented 19 years ago

Juergen Hoeller commented

If you get the chance to give this a try today, please let me know whether it works for you!

Juergen

spring-projects-issues commented 19 years ago

Keith Garry Boyce commented

As I said... It will not work for me. The problem is that struts will parse the web.xml looking for it's perceived servletName which as you said will be a struts servlet managed by the container. It uses this servlet name then to look for a mapping. I can't put 2 mappings mapping to the the same servlet because then servlet container makes no guarantees about which servlet get's called. So the servlet has to believe that it is in fact the original dispatcher servlet and use those mappings. As I indicated I have found no way to set the name automatically using requestdispatcher and so I was forced to include servlet in controller. I think it makes it cleaner anyway. i.e no fake configuration in web.xml for a servlet you should never be using/1 place for dispatcher servlet configuration. Let me know your thoughts.

Oh and by the way.... In the Javadoc can you mention I did a little coding on this. Not just provide suggestions. Always better for prospective employees :-)

i.e

spring-projects-issues commented 19 years ago

Juergen Hoeller commented

OK... I tried exactly the configuration that I've outlined in the javadoc with Struts 1.1, and it worked nicely. Unfortunately, I've haven't tried the tag before: This is where things break.

I can't believe that they are actually parsing the web.xml file: That's a pretty bad strategy, but unfortunately the Servlet spec doesn't provide the original request URL to forwarded resources. Still, hardcoding the path of and the tags and attribute names to be found in web.xml is among the worst you can do... This will break with Resin's web.xml shortcut syntax, for example!

There should be a better solution for that problem: Why not extract the request URL in the dispatcher and provide it to the view tags at a well-known location? That would even work with multiple servlet mappings points to the same dispatcher servlet. Unfortunately, Struts is coded the way it is, so we can't do anything about this...

In general, I consider the ServletWrappingController solution as cleaner: We shouldn't try to emulate a servlet lifecycle within a Spring controller but rather leave the management of servlet instances entirely to the servlet container. Looking up a servlet by name through a named RequestDispatcher handles this nicely, as long as no #?*! servlet implementation tries to parse web.xml itself...

To make my dispatching ServletWrappingController work with , we could subclass ActionServlet and override "initServlet" to use a given init-param value for the mapping. This should work nicely, as we can simply specify the URL mapping of the Spring dispatcher there. We could call such an ActionServlet subclass "WellBehavedActionServlet" ;-)

Juergen

spring-projects-issues commented 19 years ago

Keith Garry Boyce commented

1) I agree it's a bad strategy but I figure they have some rationale. 2) Perhaps we should pose the question to them. 3) Will you submit suggestion to them to allow for optional init Parameter to specify alternate mapping to use or shall I? 4) I agree the implementation you suggest is cleaner but it forces everyone using it to subclass the ActionServlet. (for now anyway) I for one wouldn't use it on that basis. Upgrades to Struts would have to be considered and the work that would have to be done to keep the subclass in sync. Also there might be other frameworks out there doing this and people using the implementation might hit the same issue I had with Struts. 5) I don't think we would be emulating a servlet lifecycle. The real servlet in this case is the DispatcherServlet and the container will manage that. What exactly are we gaining by having container manage an additional servlet? 6) You didn't address my issue about the JavaDoc comment

spring-projects-issues commented 19 years ago

Juergen Hoeller commented

Sure, it might be worth to ask the Struts guys why they chose that particular strategy (please do so if you have the chance). However, that won't change the current situation, as Struts 1.1 remains the same...

So I've just renamed my version to ServletForwardingController, and added a new ServletWrappingController implementation that follows your latest implementation in that it holds a servlet instance internally. Note that it improves on your version through taking a Class as "servletClass" parameter and destroying the servlet instance on shutdown.

Regarding the javadoc: Come on, I've never seen anyone so keen on special wording in a credit... Nevertheless, I've adapted the wording. Now let's leave it at that and concentrate on something important again, OK? ;-)

Juergen

spring-projects-issues commented 19 years ago

Juergen Hoeller commented

My new implementation of ServletWrappingController, following your latest prototype.

Note that this does not expose the WebApplicationContext as root context in the ServletContext: No controller should do this. The root context is supposed to be managed by ContextLoaderServlet.

Juergen

spring-projects-issues commented 19 years ago

Keith Garry Boyce commented

So how do the action support classes get access to web application context?

spring-projects-issues commented 19 years ago

Keith Garry Boyce commented

So how do action support classes get access to WAC?

spring-projects-issues commented 19 years ago

Juergen Hoeller commented

well, I recommend to define all your middle tier beans in an "applicationContext.xml" file, as loaded by Spring's ContextLoaderServlet (registered in web.xml). You'll get proper exposure of the root context then, seen by ActionSupport and co.

The DispatcherServlet context should be as minimal as possible. Just define web MVC stuff there, not reusable middle tier beans.

Juergen

spring-projects-issues commented 19 years ago

Juergen Hoeller commented

Did you already have a chance to try the new version, with the root context being ContextLoaderServlet-driven?

Juergen

spring-projects-issues commented 19 years ago

Keith Garry Boyce commented

2 problems

1)

Doesn't compile because @see tags in Javadoc make compiler complain about indirectly referencing Filter

2)ContextLoaderServlet initializes Spring and then DispatcherServlet re-initializes spring (double initialization).

spring-projects-issues commented 19 years ago

Juergen Hoeller commented

1) Compiles nicely as part of Spring. (I've compiled and run the test suite before I committed it, of course.) Why does a compiler complain about @see tags in the first place? Sun's javac sure enough doesn't... Anyway, simply remove those tags (if it causes issues for you) to give it a try for the time being.

2) Let me clarify a misunderstanding here: You can't double-initialize "Spring"; Spring is not a singleton system. ContextLoaderServlet loads a Spring root web application context, DispatcherServlet loads its own child application context which automatically uses the root context as parent (seeing its beans, etc). Each of those contexts has its own lifecycle. No problem there, in general: This is what all Spring web MVC applications rely on every day.

Juergen

spring-projects-issues commented 19 years ago

Keith Garry Boyce commented

1) I don't actually know why it complained for me. I compiled in eclipse and that was the result. Did you compile against a servlet 2.2 library?

2) Are you saying that the Dispatcher servlet should be accessing a different applicationContext.xml? It will only have the dispatcher specific stuff?

spring-projects-issues commented 19 years ago

Juergen Hoeller commented

No, I compiled against the Servlet 2.3 API. But that doesn't matter in the first place, as we're talking about a javadoc @see tag which the compiler is supposed to ignore!

ContextLoaderServlet by default loads from "WEB-INF/applicationContext.xml". DispatcherServlet by default loads from "WEB-INF/\-servlet".xml, e.g. "WEB-INF/dispatcher-servlet.xml" for a servlet named "dispatcher" (in web.xml).

All beans in "dispatcher-servlet.xml" will then automatically see the beans in "applicationContext.xml", to be able to reference them. Technically, we have two contexts there, with separate lifecycle, but they are connected through a parent-child visibility relationship.

It's easier to show an example than to explain, actually. Have a look at Petclinic or JPetStore or any other of the samples which come with the Spring distribution: All of them use a ContextLoaderServlet root context in combination with a DispatcherServlet child context.

Juergen

spring-projects-issues commented 19 years ago

Juergen Hoeller commented

Considered closed for the time being. Any further feedback has to go into 1.1.2.

Juergen

spring-projects-issues commented 19 years ago

Keith Garry Boyce commented

There is still a problem: On initializing Spring logs

21:19:48,030 INFO Environment:551 - JVM does not support LinkedHasMap, LinkedHashSet - ordered maps and sets disabled

I don't know if that's just cosmetic or it actually causes the implementation of LinkedMap to be not used. Please advise.

spring-projects-issues commented 19 years ago

Keith Garry Boyce commented

Actually i'm pretty sure it disables. I also see this in log

21:19:48,421 WARN Binder:520 - Attribute "order-by" ignored in JDK1.3 or less

spring-projects-issues commented 19 years ago

Juergen Hoeller commented

As far as I can tell, this is Hibernate logging... "Environment" is a Hibernate class, and "order-by" is a Hibernate mapping attribute. So you're in the wrong JIRA, sorry :-)

(And in the wrong JIRA issue, BTW: This is about HandlerInterceptors on Servlet 2.2, not about falling back to Commons Collections.)

Juergen

spring-projects-issues commented 19 years ago

Keith Garry Boyce commented

You are right on both counts sorry. I tracked it down to hibernate last night but I forgot to update JIRA.