DWR

Method cannot be found if overloaded and another overloaded method has the same parameter count.

Details

  • Type: Bug Bug
  • Status: Open Open
  • Priority: Normal Normal
  • Resolution: Unresolved
  • Affects Version/s: 3.0.M1, 3.0.RC1
  • Fix Version/s: 3.0
  • Component/s: Core
  • Documentation Required:
    Yes
  • Description:
    Hide
    The following will fail:

    public String overloaded(String string) {}
    public String overloaded(String[] stringArr) {}

    So will this:
    public String overloaded(String string, String[] stringArr) {}
    public String overloaded(String[] stringArr, String string) {}

    We can't currently call overloaded methods when the param count is the same and I don't think this is going to be an easy one to resolve.
    Show
    The following will fail: public String overloaded(String string) {} public String overloaded(String[] stringArr) {} So will this: public String overloaded(String string, String[] stringArr) {} public String overloaded(String[] stringArr, String string) {} We can't currently call overloaded methods when the param count is the same and I don't think this is going to be an easy one to resolve.

Activity

Hide
Mike Wilson added a comment - 18/Feb/10 1:06 AM

It is possible to allow method overloading based on what JavaScript allows us to test. Using our normal type detects we can distinguish between String, Boolean, Date, Number, Array and Object. Thus, in the JS world your examples would translate to
overloaded(String)
overloaded(Array)
and
overloaded(String, Array)
overloaded(Array, String)
which is ok.

But we couldn't distinguish between different sorts of arrays, f ex:
public void overloaded(String[] stringArr)
public void overloaded(Integer[] intArr)
as both these map to Array.

Object has the same problems as Array as all user-defined classes will be mapped against it but we only detect them as Object in JS. Though, if class-mapping is used then we can do full overloading on them as well.

One remaining problem is "null" [calling overloaded(null)], as it can map against any of the types, and we can't cast it to the desired type from client code. For that we would need to extend our call options to include some type hints.

I am tempted to push most of this to 4.0

Show
Mike Wilson added a comment - 18/Feb/10 1:06 AM It is possible to allow method overloading based on what JavaScript allows us to test. Using our normal type detects we can distinguish between String, Boolean, Date, Number, Array and Object. Thus, in the JS world your examples would translate to overloaded(String) overloaded(Array) and overloaded(String, Array) overloaded(Array, String) which is ok. But we couldn't distinguish between different sorts of arrays, f ex: public void overloaded(String[] stringArr) public void overloaded(Integer[] intArr) as both these map to Array. Object has the same problems as Array as all user-defined classes will be mapped against it but we only detect them as Object in JS. Though, if class-mapping is used then we can do full overloading on them as well. One remaining problem is "null" [calling overloaded(null)], as it can map against any of the types, and we can't cast it to the desired type from client code. For that we would need to extend our call options to include some type hints. I am tempted to push most of this to 4.0
Hide
David Marginian added a comment - 19/Feb/10 5:26 PM

I agree, pushing to 4.x.

Show
David Marginian added a comment - 19/Feb/10 5:26 PM I agree, pushing to 4.x.
Hide
John Redford added a comment - 23/Feb/10 8:27 AM

In order to handle the case where the Java side just needs to distinguish between "array" and "not array", this code works. It accepts JavaScript array parameters when the Java parameter is either an Array or a List – I am not aware if DWR presently handles any other implicit array conversion cases; if so, the extension is obvious.

For my purposes, this is sufficient. This also is sufficient to make the example in the documentation (http://directwebremoting.org/dwr/server/dwrxml/signatures.html) work. Having a more complicated system might be nice, but might not useful in practice, so I think it would be fine to push that off to the next major release.

Index: core/api/main/java/org/directwebremoting/extend/InboundVariable.java
===================================================================
— core/api/main/java/org/directwebremoting/extend/InboundVariable.java (revision 2999)
+++ core/api/main/java/org/directwebremoting/extend/InboundVariable.java (working copy)
@@ -153,6 +153,14 @@
}

/**
+ * @return Returns the type.
+ */
+ public String getType()
+ { + return type; + }
+
+ /**

  • @return Returns the value.
    */
    public String getValue()
    Index: core/api/main/java/org/directwebremoting/extend/Call.java
    ===================================================================
      • core/api/main/java/org/directwebremoting/extend/Call.java (revision 2999)
        +++ core/api/main/java/org/directwebremoting/extend/Call.java (working copy)
        @@ -184,6 +184,17 @@
        continue allMethodsLoop;
        }

+ if (inputType == null && !param.isNull())
+ {
+ boolean arrayLike = methodParamType.isArray() || List.class.isAssignableFrom(methodParamType);
+ if ("array".equals(param.getType()) != arrayLike)
+ { + it.remove(); + continue allMethodsLoop; + }
+ }
+
+
// Remove methods which declare more non-nullable parameters than were passed
if (inputArgCount <= i && methodParamType.isPrimitive())
{

Show
John Redford added a comment - 23/Feb/10 8:27 AM In order to handle the case where the Java side just needs to distinguish between "array" and "not array", this code works. It accepts JavaScript array parameters when the Java parameter is either an Array or a List – I am not aware if DWR presently handles any other implicit array conversion cases; if so, the extension is obvious. For my purposes, this is sufficient. This also is sufficient to make the example in the documentation (http://directwebremoting.org/dwr/server/dwrxml/signatures.html) work. Having a more complicated system might be nice, but might not useful in practice, so I think it would be fine to push that off to the next major release. Index: core/api/main/java/org/directwebremoting/extend/InboundVariable.java =================================================================== — core/api/main/java/org/directwebremoting/extend/InboundVariable.java (revision 2999) +++ core/api/main/java/org/directwebremoting/extend/InboundVariable.java (working copy) @@ -153,6 +153,14 @@ } /** + * @return Returns the type. + */ + public String getType() + { + return type; + } + + /**
  • @return Returns the value. */ public String getValue() Index: core/api/main/java/org/directwebremoting/extend/Call.java ===================================================================
      • core/api/main/java/org/directwebremoting/extend/Call.java (revision 2999) +++ core/api/main/java/org/directwebremoting/extend/Call.java (working copy) @@ -184,6 +184,17 @@ continue allMethodsLoop; }
+ if (inputType == null && !param.isNull()) + { + boolean arrayLike = methodParamType.isArray() || List.class.isAssignableFrom(methodParamType); + if ("array".equals(param.getType()) != arrayLike) + { + it.remove(); + continue allMethodsLoop; + } + } + + // Remove methods which declare more non-nullable parameters than were passed if (inputArgCount <= i && methodParamType.isPrimitive()) {
Hide
David Marginian added a comment - 26/Feb/10 2:40 PM

Need to document what is/is not supported as far as overloading is concerned.

Show
David Marginian added a comment - 26/Feb/10 2:40 PM Need to document what is/is not supported as far as overloading is concerned.
Hide
David Marginian added a comment - 26/Feb/10 2:58 PM

Also, code should be changed from:
List.class.isAssignableFrom(methodParamType);

To
Collection.class.isAssignableFrom(methodParamType);

Show
David Marginian added a comment - 26/Feb/10 2:58 PM Also, code should be changed from: List.class.isAssignableFrom(methodParamType); To Collection.class.isAssignableFrom(methodParamType);
Hide
David Marginian added a comment - 26/Feb/10 11:30 PM

John, if you want to grab the latest build from bamboo I have made some changes that should fix this for you. We know support a lot more overloading options, but the issues Mike discussed still remain.

Show
David Marginian added a comment - 26/Feb/10 11:30 PM John, if you want to grab the latest build from bamboo I have made some changes that should fix this for you. We know support a lot more overloading options, but the issues Mike discussed still remain.
Hide
David Marginian added a comment - 26/Feb/10 11:30 PM

Also Mike if you can take a look at the code when you have some time that would be helpful. I have added several more overloading tests and they are all passing.

Show
David Marginian added a comment - 26/Feb/10 11:30 PM Also Mike if you can take a look at the code when you have some time that would be helpful. I have added several more overloading tests and they are all passing.
Hide
David Marginian added a comment - 06/Aug/10 9:01 PM

Mike, I know we are going to push most of this to 4.0, but I did make some quick changes here and I want you to look them over and perhaps we should update the docs.

Show
David Marginian added a comment - 06/Aug/10 9:01 PM Mike, I know we are going to push most of this to 4.0, but I did make some quick changes here and I want you to look them over and perhaps we should update the docs.
Hide
David Marginian added a comment - 11/Aug/10 8:26 PM

Mike, assigning to you for review.

Show
David Marginian added a comment - 11/Aug/10 8:26 PM Mike, assigning to you for review.
Hide
David Marginian added a comment - 11/Aug/10 9:00 PM

Mike to save you some time looking up svn history, the changes were limited to:
Call.java
LocalUtil.java
InboundVariable.java

Revision 2997 is the revision preceding the changes.
Revision 3020 is the revision with all changes.

Show
David Marginian added a comment - 11/Aug/10 9:00 PM Mike to save you some time looking up svn history, the changes were limited to: Call.java LocalUtil.java InboundVariable.java Revision 2997 is the revision preceding the changes. Revision 3020 is the revision with all changes.
Hide
David Marginian added a comment - 13/Sep/10 8:53 PM

This change broke backwards compatibility - From the mailing list - RE: [dwr-user] RC2 strange behavior.

Basically, the user was calling a method - public void whatever(long num) { return 0L; }, but passing in a string (not a number) from the browser. This used to work but no longer works because we now check that the type passed in is consistent. I am not sure this is a huge deal, but we should probably document it. The alternative would be to add code to only make the additional type check IF the method is overloaded (which I don't think is easily determined).

Show
David Marginian added a comment - 13/Sep/10 8:53 PM This change broke backwards compatibility - From the mailing list - RE: [dwr-user] RC2 strange behavior. Basically, the user was calling a method - public void whatever(long num) { return 0L; }, but passing in a string (not a number) from the browser. This used to work but no longer works because we now check that the type passed in is consistent. I am not sure this is a huge deal, but we should probably document it. The alternative would be to add code to only make the additional type check IF the method is overloaded (which I don't think is easily determined).

People

Dates

  • Created:
    30/Jan/10 7:11 AM
    Updated:
    25/Jun/11 2:37 PM