[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