Page 1 of 2 12 LastLast
Results 1 to 10 of 11

Thread: 'Ambiguous mapping found' in controller with one POST mapping, why?

  1. #1

    Question 'Ambiguous mapping found' in controller with one POST mapping, why?

    Hi guys.
    I'm using Spring 3.2.0.RELEASE, Security 3.1.3, MVC + WebFlow 2.3.1, Spring Social + Spring Social Security (both snapshoot), + Spring mongodb stuff.

    Spring Social + Spring Social Security initially have Spring 3.1.3 dependency, but I recompiled them with Spring 3.2.0.RELEASE locally and installed by gradle build script.

    I'm trying to create 'FB canvas' app and have one controller with ONE ONLY post method and I'm getting error above.

    Code:
    @Controller
    public class CanvasProviderSignInController {
    ...... // internal variables initialized by constructor....
    
        @RequestMapping(value = "/canvas", method = RequestMethod.POST)
        public String processFaceBookCanvasRequest(
                NativeWebRequest request) {
    ..........
    return NULL!!!;
    }
    
    
    Controller initialization:
    
    @Configuration
    public class SocialAndSecurityConfig {
        @Inject
        private Environment environment;
    ....... // different stuff
    
    
       	@Bean
       	public CanvasProviderSignInController providerSignInController() {
               CanvasProviderSignInController signInController = new CanvasProviderSignInController(
                       socialAuthenticationServiceLocator(),
                       facebookServiceProvider(),
                       usersConnectionRepository(),
                       signInAdapter(),
                       signedRequestDecoder()
               );
              return signInController;
       	}
    ..........
    I even removed all code from method returning NULL only, but I'm getting error:
    Code:
    20:51:39.015 [RMI TCP Connection(3)-127.0.0.1] ERROR o.s.web.context.ContextLoader - 
    Context initialization failed
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappingHandlerMapping' 
    defined in class path resource [org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration.class]: 
    Invocation of init method failed; nested exception is java.lang.IllegalStateException: Ambiguous mapping found. 
    Cannot map 'providerSignInController' bean method 
    public java.lang.String 
    com.web.controller.facebook.CanvasProviderSignInController.processFaceBookCanvasRequest(
    org.springframework.web.context.request.NativeWebRequest)
    to {[/canvas],methods=[POST],params=[],headers=[],consumes=[],produces=[],custom=[]}:
     There is already 'canvasProviderSignInController' bean method
    public java.lang.String 
    com.web.controller.facebook.CanvasProviderSignInController.processFaceBookCanvasRequest(
    org.springframework.web.context.request.NativeWebRequest) mapped.
    .............
    Caused by: java.lang.IllegalStateException: Ambiguous mapping found. Cannot map 'providerSignInController' bean method 
    public java.lang.String 
    com.web.controller.facebook.CanvasProviderSignInController.processFaceBookCanvasRequest(
    org.springframework.web.context.request.NativeWebRequest)
    to {[/canvas],methods=[POST],params=[],headers=[],consumes=[],produces=[],custom=[]}:
    There is already 'canvasProviderSignInController' bean method
    public java.lang.String 
    com.web.controller.facebook.CanvasProviderSignInController.processFaceBookCanvasRequest(
    org.springframework.web.context.request.NativeWebRequest) mapped
    Is there chance something is wrong with libraries? Here is the list.
    Code:
    activation-1.1.1.jar
    aopalliance-1.0.jar
    attoparser-1.1.jar
    commons-beanutils-1.8.0.jar
    commons-codec-1.6.jar
    commons-collections-3.2.1.jar
    commons-digester-2.0.jar
    commons-lang-2.4.jar
    commons-logging-1.1.1.jar
    guava-13.0.1.jar
    hibernate-validator-4.3.1.Final.jar
    httpclient-4.2.2.jar
    httpcore-4.2.2.jar
    jackson-core-asl-1.9.9.jar
    jackson-mapper-asl-1.9.9.jar
    javax.inject-1.jar
    jboss-logging-3.1.0.CR2.jar
    jcl-over-slf4j-1.7.1.jar
    joda-time-2.1.jar
    jstl-1.2.jar
    logback-classic-1.0.9.jar
    logback-core-1.0.9.jar
    lombok-0.11.6.jar
    mail-1.4.5.jar
    mongo-java-driver-2.10.1.jar
    sitemesh-3.0-alpha-2.jar
    slf4j-api-1.7.2.jar
    spring-aop-3.2.0.RELEASE.jar
    spring-beans-3.2.0.RELEASE.jar
    spring-binding-2.3.1.RELEASE.jar
    spring-context-3.2.0.RELEASE.jar
    spring-context-support-3.2.0.RELEASE.jar
    spring-core-3.2.0.RELEASE.jar
    spring-data-commons-core-1.4.0.RELEASE.jar
    spring-data-mongodb-1.1.0.RELEASE.jar
    spring-expression-3.2.0.RELEASE.jar
    spring-jdbc-3.2.0.RELEASE.jar
    spring-js-2.3.1.RELEASE.jar
    spring-js-resources-2.3.1.RELEASE.jar
    spring-security-acl-3.1.3.RELEASE.jar
    spring-security-config-3.1.3.RELEASE.jar
    spring-security-core-3.1.3.RELEASE.jar
    spring-security-taglibs-3.1.3.RELEASE.jar
    spring-security-web-3.1.3.RELEASE.jar
    spring-social-config-1.1.0.BUILD-SNAPSHOT.jar
    spring-social-core-1.1.0.BUILD-SNAPSHOT.jar
    spring-social-facebook-1.1.0.BUILD-SNAPSHOT.jar
    spring-social-facebook-web-1.1.0.BUILD-SNAPSHOT.jar
    spring-social-security-1.1.0.BUILD-SNAPSHOT.jar
    spring-social-web-1.1.0.BUILD-SNAPSHOT.jar
    spring-tx-3.2.0.RELEASE.jar
    spring-web-3.2.0.RELEASE.jar
    spring-webflow-2.3.1.RELEASE.jar
    spring-webmvc-3.2.0.RELEASE.jar
    thymeleaf-2.0.16-SNAPSHOT.jar
    thymeleaf-extras-conditionalcomments-2.0.0.jar
    thymeleaf-extras-springsecurity3-2.0.0.jar
    thymeleaf-extras-tiles2-2.0.0.jar
    thymeleaf-spring3-2.0.15.jar
    tiles-api-2.2.2.jar
    tiles-core-2.2.2.jar
    tiles-jsp-2.2.2.jar
    tiles-servlet-2.2.2.jar
    tiles-template-2.2.2.jar
    validation-api-1.0.0.GA.jar
    velocity-1.7.jar
    Last edited by blandger; Jan 23rd, 2013 at 01:37 PM.
    Best regards.

  2. #2

    Default

    If I remove that controller, web-app starts fine.

    I also have following configuration stuff in related classes:
    Code:
    public class MainWebAppInitializer implements WebApplicationInitializer {
    ....// usual Dispatcher configuration with 'springSecurityFilterChain' configuration
    
    
    public class WebAppConfig extends WebMvcConfigurerAdapter {
    ......
        public void addViewControllers(ViewControllerRegistry registry) {
       		registry.addViewController("/canvas");
       	}
    ......
        @Bean
        public InternalResourceViewResolver viewResolver() {
            InternalResourceViewResolver resolver = new InternalResourceViewResolver();
            resolver.setViewClass(JstlView.class);
            resolver.setPrefix("/WEB-INF/views/");
            resolver.setSuffix(".jsp");
            resolver.setOrder(4);
            return resolver;
        }
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(localeChangeInterceptor());
    ......
        @Bean
        public LocaleChangeInterceptor localeChangeInterceptor() {
            LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
            localeChangeInterceptor.setParamName("lang"); // name of parameter for changing value
            return localeChangeInterceptor;
        }
    ........... // etc.
    Best regards.

  3. #3

    Default

    I tried following:

    1. Create two methods only inside class:

    Code:
        @RequestMapping(value = "/canvas", method = RequestMethod.GET)
        public String processFaceBookCanvasRequest2(NativeWebRequest request) {
            return null;
        }
    
        @RequestMapping(value = "/canvas", method = RequestMethod.POST)
        public String processFaceBookCanvasRequest(NativeWebRequest request) {
            return null;
        }
    It fails.
    Code:
    Caused by: java.lang.IllegalStateException: Ambiguous mapping found. Cannot map 'providerSignInController' bean method 
    public java.lang.String com.web.controller.facebook.CanvasProviderSignInController.processFaceBookCanvasRequest2(org.springframework.web.context.request.NativeWebRequest)
    to {[/canvas],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}: There is already 'canvasProviderSignInController' bean method
    public java.lang.String com.web.controller.facebook.CanvasProviderSignInController.processFaceBookCanvasRequest2(org.springframework.web.context.request.NativeWebRequest) mapped.
    	at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.registerHandlerMethod(AbstractHandlerMethodMapping.java:179) ~[spring-webmvc-3.2.0.RELEASE.jar:3.2.0.RELEASE]
    	at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.detectHandlerMethods(AbstractHandlerMethodMapping.java:145) ~[spring-webmvc-3.2.0.RELEASE.jar:3.2.0.RELEASE]

    2.
    Removing 'GET' method doesn't help. It fails on POST

    Code:
    Caused by: java.lang.IllegalStateException: Ambiguous mapping found. Cannot map 'providerSignInController' bean method 
    public java.lang.String com.web.controller.facebook.CanvasProviderSignInController.processFaceBookCanvasRequest(org.springframework.web.context.request.NativeWebRequest)
    to {[/canvas],methods=[POST],params=[],headers=[],consumes=[],produces=[],custom=[]}: There is already 'canvasProviderSignInController' bean method
    public java.lang.String com.web.controller.facebook.CanvasProviderSignInController.processFaceBookCanvasRequest(org.springframework.web.context.request.NativeWebRequest) mapped.

    3.
    I removed all
    - dependencies inside class and left only EMPTY constructor, so it's contircted without params
    - removed all imports except
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMap ping;
    import org.springframework.web.bind.annotation.RequestMet hod;
    import org.springframework.web.context.request.NativeWebR equest;

    That didn't help, it fails with same anyway.
    Best regards.

  4. #4

    Default

    OMG
    That should be included into FAQ.

    There are TWO OPTIONS:
    1. remove @Controller
    or
    2. remove @Bean
    annotation

    If I have Controller initialization in Config class:
    Code:
    @Configuration
    public class SocialAndSecurityConfig {
    .....
       	@Bean
       	public CanvasProviderSignInController providerSignInController() {
              .......... // initialization stuff
               CanvasProviderSignInController signInController = new CanvasProviderSignInController(...........);
               return signInController;
       	}
    ........
    I should completely remove @Controller annotation from class:
    Code:
    //@Controller - REMOVE!
    public class CanvasProviderSignInController {
    ...............
    Otherwise the Controller (the @Bean at the same time) initialized TWICE and those error is thrown!
    First time controller is initialized explicitly, the second time by @ComponentScan(basePackages = {..... annotation in one of Java Config classes.

    I'm stupid dobby
    Best regards.

  5. #5
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,632

    Default

    If you remove the @Controller it isn't going to be detected properly anymore... Simply exclude this class form @ComponentScan (use an exludeFilter for it).
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  6. #6

    Default

    Quote Originally Posted by Marten Deinum View Post
    If you remove the @Controller it isn't going to be detected properly anymore... Simply exclude this class form @ComponentScan (use an exludeFilter for it).
    I tried your way:
    Code:
    @Configuration
    @EnableWebMvc
    @ComponentScan(basePackages = {
            "com.web.controller", // all controllers are there
            "com.web.exception", // one global exception handler component
            "com.web.formatter", // formatter component
            "com.web.conversion" // conversion component
    }, excludeFilters = { @ComponentScan.Filter({
            Configuration.class, CanvasProviderSignInController.class
    }) }
    )
    @Import({ServiceConfig.class, SocialAndSecurityConfig.class})
    @ImportResource("classpath:/webflow-config.xml")
    public class WebAppConfig extends WebMvcConfigurerAdapter {
    ..........
    }
    but that approach produces more weird error:
    13:52:38.172 [RMI TCP Connection(2)-127.0.0.1] ERROR o.s.web.context.ContextLoader - Context initialization failed
    java.lang.IllegalArgumentException: An error occured when processing a @ComponentScan ANNOTATION type filter: class com.web.controller.facebook.CanvasProviderSignInCo ntroller is not assignable to interface java.lang.annotation.Annotation
    at org.springframework.util.Assert.isAssignable(Asser t.java:368) ~[spring-core-3.2.0.RELEASE.jar:3.2.0.RELEASE]
    ...
    13:52:38.219 [RMI TCP Connection(2)-127.0.0.1] WARN o.s.w.c.s.AnnotationConfigWebApplicationContext - Exception thrown from LifecycleProcessor on context close
    java.lang.IllegalStateException: LifecycleProcessor not initialized - call 'refresh' before invoking lifecycle methods via the context: Root WebApplicationContext: startup date [Thu Jan 24 13:52:37 EET 2013]; root of context hierarchy
    at org.springframework.context.support.AbstractApplic ationContext.getLifecycleProcessor(AbstractApplica tionContext.java:360) [spring-context-3.2.0.RELEASE.jar:3.2.0.RELEASE]
    ......
    Probably because of dependencies to 'common-module' with business/DAO/service code. I think I'd better stick with removing @Controller annotation as it works.
    Best regards.

  7. #7
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,632

    Default

    No because you have a wrong exclusion filter... Default is excludefilter based on Annotations, the CanvasProviderSignInController isn't an annotation. You need to specify a filter based on ASSIGNABLE_TYPE.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  8. #8

    Default

    Quote Originally Posted by Marten Deinum View Post
    No because you have a wrong exclusion filter... Default is excludefilter based on Annotations, the CanvasProviderSignInController isn't an annotation. You need to specify a filter based on ASSIGNABLE_TYPE.
    It would good to see correct exclusion.... for limiting 'round trips'.

    What am I doing wrong ?
    Code:
    @ComponentScan(basePackages = {
            "com.web.controller", // all controllers are there
    ..........
    }, excludeFilters = { @ComponentScan.Filter({Configuration.class}),
            @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = {CanvasProviderSignInController.class}) }
    )
    [2013-01-24 03:32:22,565] Artifact web-app: Artifact is being deployed, please wait...
    15:32:29.889 [RMI TCP Connection(3)-127.0.0.1] ERROR o.s.web.context.ContextLoader - Context initialization failed
    org.springframework.beans.factory.BeanCreationExce ption: Error creating bean with name 'requestMappingHandlerMapping' defined in class path resource [org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: Ambiguous mapping found. Cannot map 'canvasProviderSignInController' bean method
    public java.lang.String com.web.controller.facebook.CanvasProviderSignInCo ntroller.processFaceBookCanvasRequest(org.springfr amework.web.context.request.NativeWebRequest,org.s pringframework.ui.Model)
    to {[/canvas/],methods=[POST],params=[],headers=[],consumes=[],produces=[],custom=[]}: There is already 'providerSignInController' bean method
    ..................
    Best regards.

  9. #9
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,632

    Default

    Why are you loading the controllers with the ContextLoaderLIstener? Those should be loaded by the dispatcherservlet, but anyway...

    The exclusion should work if it doesn't make sure you don't have classloading issues as class identity is based on name and classloader, also make sure that if you have multiple @ComponentScan elements (on different @Configuration classes) they all scan and you need to exclude on all of them...
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  10. #10

    Default

    Quote Originally Posted by Marten Deinum View Post
    Why are you loading the controllers with the ContextLoaderLIstener? Those should be loaded by the dispatcherservlet, but anyway...
    Probably I don't know how to make that better way. I'm not sure, but looks like you are do that the same way in book. Don't you?
    Code:
    public class BookstoreWebApplicationInitializer implements WebApplicationInitializer { 
    ....
    private static final Class<?>[] configurationClasses = new Class<?>[] { TestDataContextConfiguration.class, ......
    
    	@Override
    	public void onStartup(ServletContext servletContext) throws ServletException {
    		registerListener(servletContext);
    		registerDispatcherServlet(servletContext);  
    .....
    
    private void registerListener(ServletContext servletContext) {
    		AnnotationConfigWebApplicationContext rootContext = createContext(configurationClasses);
    		servletContext.addListener(new ContextLoaderListener(rootContext));
    		servletContext.addListener(new RequestContextListener());
    	}
    
    private AnnotationConfigWebApplicationContext createContext(final Class<?>... annotatedClasses) {
    		AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
    		context.register(annotatedClasses);
    		return context;
    	}
    ......
    I'm using the similar approach and the same loading order.
    The exclusion should work if it doesn't make sure you don't have classloading issues as class identity is based on name and classloader,
    How is better to do that? By looking into code or in debugger? Anyway... it works that way...

    also make sure that if you have multiple @ComponentScan elements (on different @Configuration classes) they all scan and you need to exclude on all of them...
    I think it's not an issue, I checked twice and triple. I spent a lot of time yesterday on that. All DAO/service scanned in config classes basically inside 'common-module' and they don't have path for 'controllers' package.

    Controllers are scanned at one place only:
    Code:
    @Configuration
    @EnableWebMvc
    @ComponentScan(basePackages = {
            "com.web.controller", // all controllers are there
    .............
    }, excludeFilters = { @ComponentScan.Filter({Configuration.class}),
            @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = {CanvasProviderSignInController.class}) }
    )
    @Import({ServiceConfig.class, SocialAndSecurityConfig.class})
    @ImportResource("classpath:/webflow-config.xml")
    public class WebAppConfig extends WebMvcConfigurerAdapter {
    ............
    Best regards.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •