[Geoserver-devel] GeoServer, Spring 4, and Spring MVC interaction

I discovered an interesting behavior when working with the latest GeoServer in an application that uses Spring MVC.

This is more of an unexpected interaction between GeoServer/Spring 4 and Spring MVC than a GeoServer bug, and should probably only be handled within any GeoServer applications that actualy use Spring MVC.

Spring MVC uses MappedInterceptor to add a HandlerInterceptor to specific request paths.

The GeoServerSystemTestSupport class creates a custom HttpServlet for handling mock requests. In the service() method of this servlet, it calls GeoServerExtensions.extensions(HandlerInterceptor.class, applicationContext) to get all the global HandlerInterceptor instances to apply to the mock request. As of the Spring 4 upgrade, this call now also picks up all instances of MappedInterceptor.

Since MappedInterceptor instances are handled by the dispatcher, this means that all these MappedInterceptors now get called twice, which can lead to various anomalous behaviors. This appears to only affect test cases, and has no effect on regular GeoServer behavior.

This can be prevented by adding an ExtensionFilter to the applicationContext.xml:

public class MappedInterceptorFilter implements ExtensionFilter {
@Override
public boolean exclude(String beanId, Object bean) {
return bean instanceof MappedInterceptor;
}
}

Given that core GeoServer does not (to my knowledge) use Spring MVC, I am unsure whether or not this is something that should be including in GeoServer or left for downstream developers to handle (although I would lean towards the latter).

A quick text search shows that GeoFence does use Spring MVC, and may be affected by this issue.

Torben

Hi Torben,

A quick text search shows that *GeoFence does use Spring MVC, and may be
affected by this issue*.

Well, no interceptor is defined or called explicitly in GeoFence.
The only class explicitly used is DispatcherServlet for handling the spring
remoting calls.
Furthermore, this class is only declared in the standalone version; this means
that the gefence* community modules won't import the spring mvc dep into
geoserver by themselves (they are in the dependency tree because the root pom
imports them).

   Cheers,
   Emanuele

Alle 22:11:46 di Wednesday 6 April 2016, Torben Barsballe ha scritto:

I discovered an interesting behavior when working with the latest GeoServer
in an application that uses Spring MVC.
This is more of an unexpected interaction between GeoServer/Spring 4 and
Spring MVC than a GeoServer bug, and should probably only be handled within
any GeoServer applications that actualy use Spring MVC.

Spring MVC uses MappedInterceptor to add a HandlerInterceptor to specific
request paths.

The GeoServerSystemTestSupport class creates a custom HttpServlet for
handling mock requests. In the service() method of this servlet, it calls
GeoServerExtensions.extensions(HandlerInterceptor.class,
applicationContext) to get all the global HandlerInterceptor instances to
apply to the mock request. As of the Spring 4 upgrade, this call now also
picks up all instances of MappedInterceptor.

Since MappedInterceptor instances are handled by the dispatcher, this means
that all these MappedInterceptors *now get called twice*, which can lead to
various anomalous behaviors. This appears to *only affect test cases*, and
has no effect on regular GeoServer behavior.

This can be prevented by adding an ExtensionFilter to the
applicationContext.xml:

public class MappedInterceptorFilter implements ExtensionFilter {
    @Override
    public boolean exclude(String beanId, Object bean) {
        return bean instanceof MappedInterceptor;
    }
}

Given that core GeoServer does not (to my knowledge) use Spring MVC, I am
unsure whether or not this is something that should be including in
GeoServer or left for downstream developers to handle (although I would
lean towards the latter).

A quick text search shows that *GeoFence does use Spring MVC, and may be
affected by this issue*.

Torben

--

GeoServer Professional Services from the experts!
Visit http://goo.gl/NWWaa2 for more information.

Ing. Emanuele Tajariol
Technical Lead

GeoSolutions S.A.S.
Via di Montramito 3/A
55054 Massarosa (LU)
Italy
phone: +39 0584 962313
fax: +39 0584 1660272
mob: +39 380 2116282

http://www.geo-solutions.it
http://twitter.com/geosolutions_it

-------------------------------------------------------

Ok, geofence should be safe then. The issue should only affect test cases anyways.

Torben

···

On Fri, Apr 8, 2016 at 4:24 AM, Emanuele Tajariol <etj@anonymised.com> wrote:

Hi Torben,

A quick text search shows that GeoFence does use Spring MVC, and may be
affected by this issue
.

Well, no interceptor is defined or called explicitly in GeoFence.
The only class explicitly used is DispatcherServlet for handling the spring
remoting calls.
Furthermore, this class is only declared in the standalone version; this means
that the gefence* community modules won’t import the spring mvc dep into
geoserver by themselves (they are in the dependency tree because the root pom
imports them).

Cheers,
Emanuele

Alle 22:11:46 di Wednesday 6 April 2016, Torben Barsballe ha scritto:

I discovered an interesting behavior when working with the latest GeoServer
in an application that uses Spring MVC.
This is more of an unexpected interaction between GeoServer/Spring 4 and
Spring MVC than a GeoServer bug, and should probably only be handled within
any GeoServer applications that actualy use Spring MVC.

Spring MVC uses MappedInterceptor to add a HandlerInterceptor to specific
request paths.

The GeoServerSystemTestSupport class creates a custom HttpServlet for
handling mock requests. In the service() method of this servlet, it calls
GeoServerExtensions.extensions(HandlerInterceptor.class,
applicationContext) to get all the global HandlerInterceptor instances to
apply to the mock request. As of the Spring 4 upgrade, this call now also
picks up all instances of MappedInterceptor.

Since MappedInterceptor instances are handled by the dispatcher, this means
that all these MappedInterceptors now get called twice, which can lead to
various anomalous behaviors. This appears to only affect test cases, and
has no effect on regular GeoServer behavior.

This can be prevented by adding an ExtensionFilter to the
applicationContext.xml:

public class MappedInterceptorFilter implements ExtensionFilter {
@anonymised.com
public boolean exclude(String beanId, Object bean) {
return bean instanceof MappedInterceptor;
}
}

Given that core GeoServer does not (to my knowledge) use Spring MVC, I am
unsure whether or not this is something that should be including in
GeoServer or left for downstream developers to handle (although I would
lean towards the latter).

A quick text search shows that GeoFence does use Spring MVC, and may be
affected by this issue
.

Torben

GeoServer Professional Services from the experts!
Visit http://goo.gl/NWWaa2 for more information.

Ing. Emanuele Tajariol
Technical Lead

GeoSolutions S.A.S.
Via di Montramito 3/A
55054 Massarosa (LU)
Italy
phone: +39 0584 962313
fax: +39 0584 1660272
mob: +39 380 2116282

http://www.geo-solutions.it
http://twitter.com/geosolutions_it