SBT проблемы с моей реализацией ClassBuilder (Scala) - PullRequest
0 голосов
/ 05 июня 2018

Что 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 голосов
/ 05 июня 2018

Когда вы компилируете класс - не только класс Scala, но и класс Java - тогда это не обязательно означает, что вы получите один .class файл.

Внутренние классы, лямбды / замыкания и т. Д. Будутрезультат с дополнительным байт-кодом, который требуется для запуска и который не находится в том же файле, что и ваш «оригинальный» класс.

Насколько я могу сказать здесь, Java создал некоторый класс, потому что это телонекоторой лямбды, а вы ее не загрузили.

Итог: вам лучше загрузить все.IntelliJ мог просто передать весь путь к классу в JVM, поэтому ваш загрузчик классов, возможно, даже не использовал ваши расширения (хотя для уверенности вам пришлось бы подключить отладчик).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...