[gogo] coercion mechanism invokes foo(String) instead of foo(int) - even with 
explicit int argument
---------------------------------------------------------------------------------------------------

                 Key: FELIX-2927
                 URL: https://issues.apache.org/jira/browse/FELIX-2927
             Project: Felix
          Issue Type: Bug
          Components: Gogo Runtime
    Affects Versions: gogo.runtime-0.8.0
            Reporter: Derek Baum
            Assignee: Derek Baum


Equinox 3.7.M6 supports OSGi R4.3 which adds the overloaded method 
BundleContext.getBundle(String).

This causes gogo startup to fail, as it expects to invoke getBundle(int) but 
actually invokes getBundle(String).

Prior to R4.3, the gogo command: bundle 1
resulted in the String "1" being coerced into a long, so that getBundle(long) 
could be invoked.

Now that getBundle(String) exists, the result depends on the order that methods 
are returned from Class.getMethods(), which varies between platforms:

On Mac java version "1.6.0_24":

g! type bundle
bundle is Bundle context:bundle(long)
bundle is Bundle context:bundle()
bundle is Bundle context:bundle(String)


On Windows 2003 server, java version "1.6.0_24":
g! type bundle
bundle is Bundle context:bundle()
bundle is Bundle context:bundle(String)
bundle is Bundle context:bundle(long)

The first "exact" match wins, where "exact" just means that all supplied 
arguments are used.
On the Mac, getBundle(long) still wins, but on Windows getBundle(String) wins 
and the gogo startup scripts fails.

What's worse, is that even when you realise what is happening, it is still not 
possible to invoke getBundle(long):

g! 1L = new Long 1
g! bundle $1L

because in this case the long is coerced to a String to invoke get 
Bundle(String) and the getBundle(long) method is ignored.


There are at least two problems here:

1. the gogo coercion mechanism simply invokes the first method it can, 
regardless of whether any arguments needed to be converted.

It should instead try to score each method, perhaps adding to the score each 
time an argument needs to be converted,
then it could invoke the method with the lowest score.
However, there may still be occasions when two methods have the same score and 
gogo needs to behave deterministically
and allow either method to be invoked by supplying less ambiguous arguments.

2. all arguments in gogo start out as Strings, which make it awkward to prefer 
a method that takes an integer:
for example: g! bundle (new Long 1)

getBundle(long) is the most likely target method, but gogo does not any syntax 
to indicate that arguments should be treated as numbers rather than Strings. 
One possibility would be to recognize numbers in gogo's Tokenizer similar to 
the way that true/false are handled:

g! t = true
true
g! tt = 'true'
true
g! set t
Boolean       t               true
String          tt              true

The above shows that the bare word: true is tokenized as a Boolean, where as 
the quoted word 'true' is tokenized as a String.
So bare numbers could be tokenized as Numbers, and the existing coercion 
mechanism would convert them back to Strings as needed;
alternative by quoting something that looks like a number, you force it to be 
tokenized as a String.















--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

Reply via email to