Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BSH calling Java calls randomly an ambiguous method if var args are involved #83

Open
GoogleCodeExporter opened this issue Apr 22, 2015 · 1 comment

Comments

@GoogleCodeExporter
Copy link

What steps will reproduce the problem?
1. Modify VarargsTest as below, adding 
calling_java_varargs_or_without_should_choose_the_simplest() and the two 
overloaded methods in ClassWithVarargMethods
2. Run in Eclipse the tests from VarargsTest. My environment is eclipse 4.2 
under XP 32bits and JDK 1.7.0_7.

What is the expected output? What do you see instead?

The new test should succeed calling the simplest method being a match for two 
strings (returning 2). In my case it fails (returning 3). If I swap the two 
overloaded methods it succeeds.
If it works for you initially, swap them, retry... Junit 4.10 and J7 also 
introduces some randomness in the order the tests are executed.
Anyway. It can fail.

Yes the two methods are technically a valid match for 
helper.twoChoices("one","two").
However, like in Java you would expect the best match to be called.
What I would expect here would be to have the BSF code getting a list of all 
the matching methods and taking the closest match, not the first. It seems that 
filtering by argument types works well.

If multiple methods are a match then take the one with the least number of 
arguments.
The current behavior is random as the first match is the good one.
If you have more than one choice then I do not know.

However on my production system, in some cases the first method is called, in 
some other the second without even restarting the VM !!!

The reason is that the reflection API does not guaranty at all in which order 
the (matching/all) methods are returned for a class. 
Picking the one with the smaller number of arguments may not be totally perfect 
but this will bring a little bit of repeatability.

Thanks

public class VarargsTest {
...        

@Test
public void calling_java_varargs_or_without_should_choose_the_simplest() throws 
Exception {
    final Interpreter interpreter = new Interpreter();
    interpreter.set("helper", new ClassWithVarargMethods());
    @SuppressWarnings({"unchecked"})
    final int argPassedIn = (int) interpreter.eval("helper.twoChoices(\"one\",\"two\")");
    Assert.assertEquals("Not picking the simplest choice",2,argPassedIn);
}

public static class ClassWithVarargMethods {
    ...
    /** I DO NOT expect string/string/varargs to be called */
    public int twoChoices(final String string1, final String string2, final Object ... args) {
        return 3;
    }
    /** I expect string/string to be called */
    public int twoChoices(final String string1, final String string2) {
        return 2;
    }
    ...
}

Original issue reported on code.google.com by [email protected] on 12 Nov 2012 at 9:43

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant