Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call T eq(Object) method of Java interface from Scala?

Tags:

java

scala

Scala defines an AnyRef class which is after compilation interpreted somewhat as Java's Object class. The AnyRef class, however, is not exactly equivalent to Object from the language point of view, because it introduces several new methods, such as eq(), which takes AnyRef and returns Boolean and compares references for identity

If there is a class in Java which itself defines the eq() method with a different result type and an interface which this class implements also having this method:

public interface I {
    String eq(Object that);
}

public class A implements I {
    public String eq(Object that) {return "";}
}

then its eq method becomes inaccessible to Scala code if called via interface reference

val i: I = new A
val a = new A
val b = Some(1)           //whatever actually
val s1: String = a.eq(b)   //compiles OK
val s2: String = i.eq(b)   //compilation error

The eq method Scala knows about here is the eq method from the AnyRef class being "glued" to interface I which came from Java without that method, but with an eq() method of its own with a different result type. I can explain this behavior, but can't solve the real-life task when I have to call this Java eq() method without a possiblity to modify the code of the Java third-party library. Namely I'm talking about Liferay and its Dynamic Query API and the interface named com.liferay.portal.kernel.dao.orm.Property. It has an eq() method taking Object and returning Criterion. This code won't compile in Scala:

val query = DynamicQueryFactoryUtil.forClass(classOf[BookmarksEntry])
.add(PropertyFactoryUtil.forName("folderId").eq(new Long(folderId)))

because eq won't be interpreted correctly. Just to mention, the Property class has another overload of the eq() method which takes DynamicQuery as parameter. This overload is accessible from Scala.

Do you know of any way to call that eq(Object) method of Java interface from Scala?

Scala version used is 2.8.1

like image 778
kyrel Avatar asked Aug 31 '11 21:08

kyrel


2 Answers

Interesting problem: I hadn't seen this one before. I don't know how to solve it in Scala, or even if it is possible at all. On such situations, however, the best you can do is create a wrapper in Java. For example:

public class Eq {
    static public String eq(I obj, Object that) {
        return obj.eq(that);
}

You then just call Eq.eq(x, y) instead of x.eq(y).

like image 149
Daniel C. Sobral Avatar answered Oct 06 '22 17:10

Daniel C. Sobral


You can do it via reflection, but I don't know if that's what you'd want since it's kind of ugly.

FWIW, you can do it by:

i.getClass().getMethod("eq", classOf[Object]).invoke(i, "a").asInstanceOf[String]
like image 43
thatsmydoing Avatar answered Oct 06 '22 18:10

thatsmydoing