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文件而不是只传递一个类文件吗?
答案 0 :(得分:0)
当你编译一个类 - 不仅是Scala类,Java类 - 那么它并不一定意味着你将得到一个.class
文件。
内部类,lambdas / closures等将产生额外的字节码,这是运行所必需的,并且与“原始”类不在同一个文件中。
据我所知,Java创建了一些类,因为它是一些lambda的主体,并且你没有加载它。
底线是:你最好加载一切。 IntelliJ可能只是将整个类路径传递给JVM,因此您的类加载器可能甚至没有使用您的扩展(尽管您必须附加调试器才能确定)。