[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