This project is read-only.
1

Closed

Overloaded actions causes 500 error - 'Ambiguous match found'

description

Received a 500 error requesting http://-/objects/AdventureWorksModel.SalesOrderHeader/72453/actions/AppendComment from the demo server on Fri, 06 Jul 2012 03:23:49 GMT:

{"message":"Ambiguous match found.","stackTrace":[" at System.RuntimeType.GetMethodImpl(String name, BindingFlags bindingAttr, Binder binder, CallingConventions callConv, Type[] types, ParameterModifier[] modifiers)\r"," at System.Type.GetMethod(String name)\r"," at NakedObjects.Surface.Nof4.Wrapper.NakedObjectActionWrapper.get_IsQueryOnly()\r"," at NakedObjects.Surface.Nof4.Wrapper.NakedObjectActionWrapper.GetScalarProperty(ScalarProperty name)\r"," at NakedObjects.Surface.ScalarPropertyHolder.GetScalarProperty[T](ScalarProperty name)\r"," at NakedObjects.Surface.Utility.NakedObjectsSurfaceExtensions.IsQueryOnly(INakedObjectActionSurface nakedObjectActionSurface)\r"," at RestfulObjects.Snapshot.Representations.ActionRepresentation.CreateActionLink(HttpRequestMessage req, ActionContextSurface actionContext)\r"," at RestfulObjects.Snapshot.Representations.ActionRepresentation.SetLinks(HttpRequestMessage req, ActionContextSurface actionContext)\r"," at RestfulObjects.Snapshot.Representations.ActionRepresentation..ctor(HttpRequestMessage req, ActionContextSurface actionContext, RestControlFlags flags)\r"," at RestfulObjects.Snapshot.Representations.ActionRepresentation.Create(HttpRequestMessage req, ActionContextSurface actionContext, RestControlFlags flags)\r"," at RestfulObjects.Snapshot.Utility.RestSnapshot.<>c__DisplayClass16.<.ctor>b__14()\r"," at RestfulObjects.Snapshot.Utility.RestSnapshot.Populate()"],"links":[],"extensions":{}}
Closed May 9, 2013 at 4:39 PM by RichardPawson

comments

RichardPawson wrote Jul 6, 2012 at 9:43 AM

Hmm. The issue here, I think, is that there is an overloaded method AppendComment (i.e. more than one method of the same name, but different parameters). The underlying framework (Naked Objects) can cope with overloaded methods, but, currently, I don't think that the Restful Objects spec can.

In the short run we could modify the framework to just ignore overloaded method (e.g. only present the first declared one, or the simplest one) rather than throw an error. But we probably need to extend the RO spec to cope with overloaded methods.

dkhaywood wrote Jul 6, 2012 at 1:02 PM

I don't think that the spec itself needs changing, but it probably needs a new section clarifying how implementations should handle this.

Which is...

The format of the action identifier within the URL isn't defined by the spec, so any unique identifier can be used. In the case of an overloaded action, the implementation can merely needs to take appropriate steps to make that action identifier unique. (It probably should document this for anyone who wants to invoke URLs using templated actions).

For example, if there is:

AppendComment(String x)

and

AppendComment(String x, int y)

then the implementation could use the number of arguments as a distinguisher, eg "AppendComment1" and "AppendComment2". This simple encoding ought to suffice in the vast majority of cases.

If the implementation happens to have overloads with the same number of arguments, eg:


AppendComment(String x)

and

AppendComment(int y)

then the implementation will need another means to encode a unique ID. In the Java language spec this is formalized so that, for example I = int, and S = string (see http://dev.kanngard.net/Permalinks/ID_20050509144235.html for full example).

Thus, the above could be "AppendComment_S" and AppendComment_I" respectively.

Where things will be the most complicated is when the overloading is through an entity type, eg:

AppendComment(CommentType t, String x)

and

AppendComment(PriorityType t, String x)

In this case the unique identifier could use the type identifier of the referenced types, eg "AppendComment_CTP_S" and "AppendComment_PTY_S".

RichardPawson wrote Jul 6, 2012 at 1:31 PM

That makes sense, Dan.

As a short term fix we may temporarily ignore the overloaded actions but will leave the issue open to fix properly along the lines suggested.

(in Naked Objects MVC all over-loaded actions are automatically disabled - due to potential conflicts in the HTML ids. When we fix this for RO, we could probably fix it for MVC in the same manner)

Richard

dkhaywood wrote Jul 13, 2012 at 12:08 PM

RichardPawson wrote Sep 27, 2012 at 5:41 PM

Pending the RO spec specifying an official approach, we will take the temporary measure of just making the system fail fast i.e. fail at start up with a clear message that 'overloaded methods are not currently supported as actions.'

Note: Given that Naked Objects MVC has never supported overloaded actions anyway - this can be done in the framework. In future we could change that for both.

scascarini wrote Sep 28, 2012 at 11:53 AM

For the moment added code to improve error message - now indicates problem (overloaded action) class and actions at fault.

dkhaywood wrote May 7, 2013 at 10:08 PM

Has been added into RO spec v1.1...

id and URL of the action must be unique, spec does not say how implementation does this.

New discussion chapter at end outlines an algorithm:

Suppose that a domain object has:
appendComment(String x, boolean b)
and
appendComment(int y, char c)
and
appendComment(Product p, long z)

One option is simply to number them:
• appendComment1
• appendComment2
• appendComment3

Alternatively, the datatype may be used. The Java language specification defines 1 character identifies for each of its 8 primitives, so this something similar could be adopted:
• appendComment_S_Z
• appendComment_I_C
• appendComment_PRD_L"