我的ClassBuilder实现(Scala)的sbt问题

时间:2018-06-05 07:35:44

标签: java scala intellij-idea sbt runtime

Intellij为我做什么,sbt不是?

我正在开发一个Scala项目,我想支持用户定义的插件类。我已经实现了ClassLoader的子类:

class PluginLoader(directory: String) extends ClassLoader {

  override def findClass(className: String): Class[_] = {
    val bytes = loadClassData(className)
    defineClass(className,bytes,0,bytes.length)
  }

  def loadClassData(className: String): Array[Byte] = {
    val fileName = className.replace('.',File.separatorChar) + ".class"
    val file = new File(directory,fileName)
    val bytes = new Array[Byte](file.length.toInt)
    val inputStream = new DataInputStream(new FileInputStream(file))
    inputStream.readFully(bytes)
    inputStream.close()
    bytes
  }
}

我用用户定义的目录和预编译的scala类的名称来调用它:

new PluginLoader(directory).loadClass(className).newInstance()

findClass似乎成功找到了用户提供的类。但是,然后再次调用它来查找scala.runtime.java8.JFunction2$mcIII$sp.class。它在用户提供的目录中查找,因此找不到加载的类。

这是我得到的错误:(run-main-0) java.io.FileNotFoundException: ./scala/runtime/java8/JFunction2$mcIII$sp.class (No such file or directory)

我已经在Intellij中成功运行了这个应用程序,这让我觉得我在sbt中缺少一些配置,而且Intellij正在抓住我的错误。

我是否需要进行其他配置?我应该加载整个jar文件而不是只传递一个类文件吗?

1 个答案:

答案 0 :(得分:0)

当你编译一个类 - 不仅是Scala类,Java类 - 那么它并不一定意味着你将得到一个.class文件。

内部类,lambdas / closures等将产生额外的字节码,这是运行所必需的,并且与“原始”类不在同一个文件中。

据我所知,Java创建了一些类,因为它是一些lambda的主体,并且你没有加载它。

底线是:你最好加载一切。 IntelliJ可能只是将整个类路径传递给JVM,因此您的类加载器可能甚至没有使用您的扩展(尽管您必须附加调试器才能确定)。