在运行时在scala中加载java类

时间:2017-02-02 16:22:28

标签: scala reflection

我有一个带有java类的JAR文件,我想在我的scala应用程序中使用它。我不想将JAR添加到 lib / 文件夹,因为每次更改JAR时我都不想重建我的scala应用程序。

所以我尝试使用scala反射和类加载器,我能够加载该类,但我不知道如何在我的scala应用程序中进一步使用该类的方法。

到目前为止,这是我的尝试,

scala> var classLoader = new java.net.URLClassLoader(Array(new File("java-module.jar").toURI.toURL),this.getClass.getClassLoader)
classLoader: java.net.URLClassLoader = java.net.URLClassLoader@130b3958

scala> var javaClass = classLoader.loadClass("com.sample.myClass")
javaClass: Class[_] = class com.sample.myClass

scala> javaClass.getMethods.foreach(println)
public java.lang.String com.sample.myClass.myMethod(java.lang.String)
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()

我想从新加载的类中使用 myMethod 方法。

如何进一步创建此特定类的对象并使用它的方法?

编辑:为每行执行的代码添加了输出

2 个答案:

答案 0 :(得分:1)

如果加载的类在运行时具有未知类型(例如,它没有实现Scala代码已知的接口),则只能使用反射来访问字段并运行方法。

  

如何进一步创建此特定类的对象

如果类有一个公共的无参数构造函数,你可以使用javaClass.newInstance()构造它,否则你需要找到正确的构造函数(类似于列出方法时的方法,有几种方法)并调用它。有关详细信息,请参阅http://tutorials.jenkov.com/java-reflection/constructors.html

  

并使用它的方法?

您从类中获取正确的Method对象,并将其称为myMethod.invoke(myObject, args)。有关详细信息,请参阅http://tutorials.jenkov.com/java-reflection/methods.html

答案 1 :(得分:1)

由于您希望能够在重新启动时加载jar,因此您不需要使用反射。把你的java jar放在scala jar外面的类路径上。更新jar时,只需将其替换为新版本即可。只要没有重大变化,您就不需要重建scala jar。