Unexpected "IllegalStateException: Ambiguous mappng found" thrown by Spring MVC in standalone tomcat - spring-mvc

I noticed a weird behavior in my Spring MVC application:
My request mappings are all unique and I am positive there are no ambiguous mappings. I can run my app fine in STS's embedded tomcat.
However when I drop a jar in a standalone tomcat, I systematically get an ambiguous mapping error as show below.
Stacktrace:
IllegalStateException: Ambiguous mapping found. Cannot map 'preferenceController' bean method
public java.lang.String com.bignibou.controller.PreferenceController.modifyEmail(com.bignibou.controller.helpers.EmailInfo,org.springframework.validation.BindingResult,org.springframework.ui.Model)
to {[/preferences/email],methods=[POST],params=[],headers=[],consumes=[],produces=[text/html],custom=[]}: There is already 'preferencesController' bean method
public java.lang.String com.bignibou.controller.PreferencesController.modifyEmail(com.bignibou.controller.helpers.EmailInfo,org.springframework.validation.BindingResult,org.springframework.ui.Model) mapped.
Has anyone seen this problem before? FYI, I run tomcat 7.0.35 and spring 3.2.

It looks like you have two different classes: PreferenceController and PreferencesController with the same method. Just delete one of the modifyEmail methods and see if it works.

Related

AmbiguousMatchException: The request matched multiple endpoints

I am using the Ardalis Clean Architecture for one of my projects. I am getting the above-mentioned error if I have the same action method (for example: Edit) in more than one controller and I try to call that method from anywhere. But if I add the following line in the controller just above where you declare public class and the controller name then the error disappear.
[Route("[controller]/[action]")]
I don't face the same issue in a normal asp.net core 6.0 project so I guess there is something in the Ardalis Clean Architecture template that is causing this.

Mocking WebapplicationContext in Junit test case

I am trying to run a Junit test case for a method which uses webapplication context internally. However my problem is that I can not create or mock WebApplicationContext in Junit. When application is build and run then the actual code executes fine and webapplication context is created but in Junit it can not create the same.
My test case has below tags
#WebAppConfiguration
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration("classpath:applicationcontext.xml")
The method which I am trying to test has below code
WebApplicationContext context =
ContextLoader.getCurrentWebApplicationContext();
context.getBean("checkStatus", checkStatus.class);
At this point I get null pointer exception as it can not get webapplication context from ContextLooader, Can I mock this some how so that it does not give null pointer or some how can I get the actual webapplication context so that I can use it.
Should I add some code for WebApplicationContext loading in my application context xml file. In my web.xml file there is an entry regarding ContextLoaderListener should I read configuration from web.xml also in my Junit Test case?
Please provide some suggestion.
there's a lot missing from you question, including details of your environment, version numbers, and especially the exact problem you're trying to solve.
we run junit and spring boot flawlessly using the instructions in https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html#boot-features-testing-spring-boot-applications-testing-with-running-server .
but since we have no information about your use case, i can't tell whether that would work for you or not.

How does Spring portlet MVC 3.1 determine which annotated method to render with multiple controllers?

We have encountered a problem using Spring Portlet MVC 3.1 when using multiple controller classes and the DefaultAnnotationHandlerMapping.
Background
We are using Spring Portlet MVC 3.1 with annotations for the Render & Action phases
We are using JBoss EPP 5.1.1
Issue
For a Portlet render request with params, an incorrect page is rendered in the portlet
Cause
Spring Portlet MVC is using a different method for #RenderMapping than the expected method with the correct annotations
Technical Analysis
All our controllers contain #RenderMapping and #ActionMapping annotations, and all have “params” arguments to ensure that the expected method is invoked based on a parameter set in our portlet URLs. For default rendering, we have a method that has a #RenderMapping annotation with no “params” argument, which we use to render a blank JSP when the request contains no parameters.
Based on the reading of Chapter 7 and 8 in your book, we learnt that the Dispatcher Portlet tries to get the appropriate handler mapping for the incoming request and send it to the appropriate method in the controller bean configured. Our assumption was that our default #RenderMapping annotation (with no params) would only be invoked after it has checked that there are no other methods in the Controllers with an annotation that matches the specific request parameters.
However, we have debugged to realise that this assumption is incorrect. The DefaultAnnotationHandlerMapping appears to traverse through the available list of annotations in the Controller beans in some pre-defined order. This means that if the controller bean with the default #RenderMapping annotation (with no params)appears before in the list, the method with the default #RenderMapping annotation (with no params) will be invoked rather than the correct which is further down the list.
Manifested Error
We are developing in a Windows environment and deploying to a Linux environment. In Windows we see that the handler cycles through the controller beans in alphabetical order, so we initially solved our problem by adding the #RenderMapping annotated method with no params in the controller with the bean name closest to ‘Z’.
In Linux, however, it appears that the controller beans are detected in a different order. I have attached the Spring logs below to highlight the issue. The no params #RenderMapping annotation is in the YourDetailsController, and as you can see in the Windows log it appears last in the list, whereas in Linux it doesn’t. This means that if we try to access one of the controllers that appears after the YourDetailsController in the list we instead always end up hitting the no params annotation in the YourDetailsController instead.
Questions
Is our assumption incorrect?
Does our diagnosis reflect expected behaviour? Or is it a bug with Spring Portlet MVC?
Is there a different way to get the annotations scanned to form the handlermapping bean list?
Would using xml configuration (instead of annotations) remove our problem?
Would we able to define multiple handler mapping and order so that the default handler mapping is the last handler mapping used by the dispatcher portlet?
Any thoughts or advice you have on this problem would be greatly appreciated.
Mike. I'm experiencing the exact same problem. I'm using JDK 7, Spring 3.1.1.RELEASE and Hibernate 4.1.3.Final. I'm developing on Linux (Fedora) and deploying on Linux (Fedora and SL).
I was stuck because I was sure the pieces (controllers) were working one at a time but together the call to a render request was randomly ignored. Sometimes changing something would make things work again on a render request but they never worked all together.
As Walter suggested, when I isolated the controller containing only the default render request in its own package, left only the default render request in it (before I had the delete/view requests) and separated the scan of controllers in the portlet's XML configuration in two with the scanning of the default controller after the others, suddenly everything works like a charm.
It would be interesting to see if this bug is in the Spring tracker...
I'd been bitten by this problem recently, so thought I'd add some additional information based on what I found.
In my case, my default controller (with empty #Controller and #ActionMapping annotations) was always getting invoked, even though there were more specifically annotated controllers/actions (such as #Controller(XXXX) or #ActionMapping(YYYY)). What made my case weirder was that it worked OK in Tomcat/Pluto, but not in WAS/WebSphere Portal Server.
As it turns out, there is a bug introduced in 3.1.x of Spring that means the annotation handlers aren't sorted properly. See https://jira.springsource.org/browse/SPR-9303 and https://jira.springsource.org/browse/SPR-9605. Apparently, this is fixed in 3.1.3.
The big mystery to me was why it was working in Tomcat but not WebSphere? The underlying cause is that Pluto (2.0.3) uses Sun JRE 1.6.0 whereas WebSphere uses IBM JRE 1.5.0. The two JREs have a different implementation of Collections.sort() that results in a different output order when ordering array elements that are reporting they are equal (that is, the result of the compareTo() function). Because of the above Spring bug (which reports some handlers as being equal when it shouldn't) it means that the ordering of the handlers was non-deterministic across the two JREs.
So, in my case, the IBM JRE just happened to put the default controller as the very first element, and so it would be picked up every time. One way that we can affect the ordering of "equal" handlers (where "equal" is a dodgy definition due to the Spring bug) is to change the order that they are found by Spring - which affects the order of the input into the sort routine. That is why, per the above posts, moving the controller from the component scan to being explicitly listed in the XML config works. In my case, it was sufficient to make my default controller's package the last entry in my component scan. I didn't need to move it to the XML config.
Anyway, hope this helps shed a little more light on what is happening.
Response received from Ashish Sarin:
Hi Mike,
Though I haven't tested the exact same scenario that you are following
in your project, but I can say that it doesn't look like the right
approach to define your controllers. If your controllers only make use
of #RenderMapping and #ActionMapping annotations, then it might be
difficult for the developers to find out the exact controller
responsible for handling an incoming portlet request. I would
recommend that you make use of #RequestMapping at the type-level to
map portlet request to a particular controller, and use request
parameters to further narrow down the request to a particular method
in the controller.
Let me know if you still face any issue with this approach.
Mike, Your description is exactly the same issue we are running into. In Windows, we implemented the same workaround (prefixed the controller with the default rendering with a Z) and that solved it. That same code in a Linux environment has the same issues as yours. It looked like it was a times stamp issue ordering as the methods that weren't getting picked, but no luck going that route.
I assumed this was a spring bug.
I think the approach here is ok - we want different controllers handling different functions, but we want a default controller.
I just found one workaround for now. I moved the controller with the default rendering method to a different package so it is not included in the component-scan.
I add that controller manually (in the portletname-portlet.xml file) after the component-scan line, so it adds that as the last controller.
We use context:component-scan (in nnn-portlet.xml) to divide controllers default render mappings between portlet.

which jar contains org.springframework.util.MultiValueMap in spring2.5?

I am using spring2.5. and trying to implement a custom CommonsMultipartResolver for ajax upload.
After I submited form, I got following error:
org.springframework.web.util.NestedServletExceptio n: Handler processing failed; nested exception is java.lang.NoSuchMethodError: org.springframework.web.multipart.commons.CommonsF ileUploadSupport$MultipartParsingResult.getMultipa rtFiles()Lorg/springframework/util/MultiValueMap;
It seems that I need class org.springframework.util.MultiValueMap. But I can not find it anywhere in spring2.5.
Can you tell me which jar contains it?
thanks
It supposed to be in org.springframework.core...jar file, but such class does not exist in Spring 2.5
http://static.springsource.org/spring/docs/2.5.0/api/org/springframework/util/package-summary.html
It was added only in Spring 3.0.x
http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/util/package-tree.html
I think you may be mixing versions of spring jars, since the 2.5 version returns a regular Map as parameters to the getMultiPartFiles() method (javadoc). The 3.0.x version uses MultiValueMap (javadoc).
It's not the map type that is missing, but the method. Check that you are using spring-web version that matches the rest of your spring dependencies.

Method 'XYZ' cannot be reflected

We have consumed a third party web service and are trying to invoke it from an ASP.NET web application.
However when I instantiate the web service the following System.InvalidOperationException exception is thrown:
Method 'ABC.XYZ' can not be reflected.
System.InvalidOperationException:
Method 'ABC.XYZ' can not be reflected.
---> System.InvalidOperationException: The XML element 'MyDoc' from namespace
'http://mysoftware.com/ns' references
a method and a type. Change the
method's message name using
WebMethodAttribute or change the
type's root element using the
XmlRootAttribute.
From what I can gather there appears to be some ambiguity between a method and a type in the web service.
Can anyone clarify the probably cause of this exception and is there anything I can do to rectify this or should I just go to the web service owners to rectify?
Edit: Visual Studio 2008 has created the proxy class. Unfortunately I can't provide a link to the wsdl as it is a web service for a locally installed thrid party app.
I ran into the same problem earlier today.
The reason was - the class generated by Visual Studio and passed as a parameter into one of the methods did not have a default parameterless constructor. Once I have added it, the error had gone.
It seems the problem is down to data type issues between VS and the web service that was written in Java.
Ultimately it was fixed by manually editing the class and schema files that were created by VS.
I have come across the exact same problem when I was consuming a 3rd party web service. The problem in this instance was that the mustUndertand property in the reference file was looking for a Boolean, whereby the namespace property looked for a string.
By looking through the reference i was able to idenitfy the offending property and simply add "overrides" to the method signature.
Not ideal as any time you update the service you have to do this but I couldn't find any other way around this.
To find the reference file select "all files" from the solution explorer
Hope this helps
I'm guessing the wsdl emitted by or supplied with the service is not in a form that wsdl.exe or serviceutil can understand - can you post the wsdl or link to it?
how are you creating the proxy classes?
Also you might like to try and validate the wsdl against the wsdl schema to check its valid
In my case I was getting a "method cannot be reflected" error due to that fact that in the class being returned by method, I had failed to expose a default parameter-less constructor.
I was working in VB.NET. In my return class I had declared a "New(..)" method that took a couple parameters (because that is how I wanted to use it in my code). But by doing so, I had supressed the default (hidden) parameterless New() constructor that VB adds behind the scenes. Apparently the web service handler requires that a parameterless constructor be available. As soon as I added back into my class a parameterless New() constructor, it all worked fine.
I got the same message but mine was caused by a missing System.Runtime.Serialization.dll since I tried to run a 3.5 application on a machine with only .NET 2.0 installed.
I had the same issue but I found that one of the WebMethod parameters has a member that is of type interface that is why VS could not serialise it. here is the exception when trying to download the disco file
System.InvalidOperationException: Cannot serialize member
'Leopard.JobDespatchParameters.SendingUser'
of type 'Leopard.Interfaces.IUser', see inner exception for more
details. ---> System.NotSupportedException: Cannot serialize member
Leopard.JobDespatchParameters.SendingUser
of type Leopard.Interfaces.IUser because it is an interface.
Old thread but I had a different issue, Maybe of help to someone. referenced dlls were mixed up between two versions on data layer and service layer that caused the problem.
Another scenario where this error can happen: I simply had another web method with the same name (but different parameters)in my web service that slipped in during a code merge. After I deleted the old method it worked.

Resources