0

I'm trying to use java's reflection API on scala. I have a KDTree class loaded from bytecode using a ClassLoader. Here's it's methods:

public class KDTree
{
public KDTree(int k)
public void insert(double[] key, Object value) throws Exception
public Object[] range(double[] lowk, double[] uppk) throws Exception
}

And here's my wrapper scala class:

class KDTree( dimentions: Int )
    //wrapper!
    {
    private val kd= Loader.loadClass("KDTree")
    private val constructor= kd.getConstructor(java.lang.Class.forName("java.lang.Integer"))
    val wrapped= constructor.newInstance("1")
    def insert( key:Array[Double], element:Object)=
        kd.getDeclaredMethod("insert", classOf[Array[Double]])
            .invoke(key, element)
    def range( lowkey:Array[Double], highkey:Array[Double])=
        kd.getDeclaredMethod("range", classOf[Array[Double]])
            .invoke(lowkey, highkey)
    }

When I try to initialize I get an error:

java.lang.NoSuchMethodException: KDTree.<init>(java.lang.Integer)

However, the constructor's only argument is indeed a integer!

Also, I can't simply do java.lang.Integer.class, since scala complains of the syntax: error: identifier expected but 'class' found.

Does anyone have any tips?

EDIT Here is my finished code, in case someone has a use for it:

class KDTreeWrapper[T]( dimentions: Int )
{
private val kd= Loader.loadClass("KDTree")
private val constructor= kd.getConstructor(classOf[Int])
private val wrapped= constructor.newInstance(dimentions:java.lang.Integer)
    .asInstanceOf[Object]
private val insert_method= kd.
    getMethod("insert", classOf[Array[Double]], classOf[Object])
private val range_method= 
    kd.getMethod("range", classOf[Array[Double]], classOf[Array[Double]])
def insert( key:Iterable[Double], element:T)=
    insert_method.invoke(wrapped, key.toArray, element.
        asInstanceOf[Object])
def range( lowkey:Iterable[Double], highkey:Iterable[Double]):Array[T]=
    range_method.invoke(wrapped, lowkey.toArray, highkey.toArray).
        asInstanceOf[Array[T]]
}
2

2 Answers 2

3

Your problem is that you try to load a constructor with a type parameter java.lang.Integer. Try it with int.class.

Also it is shorter to write kd.getConstructor(int.class).

Sign up to request clarification or add additional context in comments.

2 Comments

as I mentioned, in scala anything.class complains
Use classOf[Integer] or classOf[int] ans described here.
1

I think my example is a lot simpler, but that could be because I wrote it:

class Config {
  val c = "some config"
}

class Moo(c: Config) {
  val x = "yow!"
}

class Loo(c: Config)  extends Moo(c) {
  override val x = c.c + " yodel!"
}

object CallMe {
  def main(args: Array[String]) {
    val cn = new Config

    // val m: Moo = new Loo(cn)

    val c = Class.forName("Loo")
    val ars = c.getConstructor(classOf[Config])
    val m: Moo = ars.newInstance(cn).asInstanceOf[Moo]

    println(m.x)
  }
}

prints out

some config yodel!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.