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

Cannot call a Java method whose parameter is RubyArray when it is overloaded #1643

Closed
Omegas7 opened this issue Apr 18, 2014 · 4 comments
Closed

Comments

@Omegas7
Copy link

@Omegas7 Omegas7 commented Apr 18, 2014

Have a Java method that accepts a RubyArray parameter. If you call it, it works fine. But then, if you overload that method with another with a different parameter, you won't be able to call the RubyArray one:

    import javax.script.*;

    import org.jruby.RubyArray;

    public class Main {
        public static void main(String[] args) throws ScriptException, NoSuchMethodException {
            Main app = new Main();
        }
        public Main() throws ScriptException, NoSuchMethodException {
            ScriptEngine jruby = new ScriptEngineManager().getEngineByName("jruby");
            jruby.eval("include Java;\n" + "def start(main) main.test([1,2,3]); end");
            Invocable invocable = (Invocable)jruby;
            invocable.invokeFunction("start",this);
        }
        public void test(int x) {
            System.out.println(x);
        }
        public void test(RubyArray array) {
            System.out.println(array);
        }
    }

If you run that code, JRuby will tell you that there are no methods for the parameter RubyArray, and then it will mention that there are two overloads available: (int) and (RubyArray), which doesn't make any sense.

JRuby 1.7.11 building with Java SE 6 on Eclipse Kepler for Mac.

@masover
Copy link

@masover masover commented Apr 29, 2014

I can reproduce this with 1.7.12 and OpenJDK 1.7.0. It also shows up with static methods -- I simplified to this Java class:

import org.jruby.RubyArray;

public class Foo {
    public static void test(int x) {
        System.out.println(x);
    }
    public static void test(RubyArray array) {
        System.out.println(array);
    }
}

I can compile that, and then open IRB, and:

Java::Foo.test 42

works as expected, but:

 Java::Foo.test [1,2,3]

fails exactly as you describe. Swapping the order of the calls or method definitions has no effect. But the RubyArray method does work, so long as it's not overloaded.

@masover
Copy link

@masover masover commented May 1, 2014

Potential workaround: Instead of working with RubyArray directly, use the List interface:

import java.util.List;
public class Foo {
    public static void test(int x) {
        System.out.println(x);
    }
    public static void test(List<?> array) {
        System.out.println(array);
    }
}

For whatever reason, there's at least one chunk of the dispatch code that's interpreting RubyArray as a List. This makes some sense, since it's incredibly handy to be able to call Java methods that expect Lists and give them Ruby arrays instead.

@Omegas7
Copy link
Author

@Omegas7 Omegas7 commented May 3, 2014

Thanks @masover, I will use your proposed workaround for the time being. This is fairly weird.

@kares
Copy link
Member

@kares kares commented Jan 19, 2017

the resolution logic deal with Java types (and their mappings to Ruby types) but having the 'native' Ruby types recognized might be useful as well ... let's see how that goes.

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

Successfully merging a pull request may close this issue.

3 participants
You can’t perform that action at this time.