Как вызвать функцию scala с параметрами с помощью загрузчика классов java?

Я ищу некоторые рекомендации по загрузке jar scala в загрузчик классов java. Функция ниже работает для меня, когда я использую файл java jar.

где arr — это массив java.net.URL для всех банок, которые мне нужно загрузить в загрузчик классов.

val classLoader = new URLClassLoader(arr, this.getClass().getClassLoader())
val clazz = classLoader.loadClass(className)
val myMethod = clazz.getDeclaredMethod(methodName, classOf[String])
myMethod.setAccessible(true)
val response = myMethod.invoke(methodName)

Однако, когда я пытаюсь использовать аналогичный метод для вызова функции scala из файла jar scala, я получаю исключение classNotFound Exception в val clazz = classLoader.loadClass(className) в этой строке.

val clazz = classLoader.loadClass("com.testing.Test")

Я хочу вызвать метод печати класса Test. Может кто-нибудь, пожалуйста, руководство? Я проверил пару других сообщений в SO, но они имеют дело с объектами и чертами, которые могут быть неприменимы для моего варианта использования.

Класс Scala, например:

package com.testing
    class Test(){
      def print (a: String, b: String): String = {
       return a+b
      }
    }

Спасибо!


person Dwarrior    schedule 27.07.2018    source источник
comment
Я думаю, что ваш пример класса Scala неверен. Это невозможно ("a": String, "b": String).   -  person tea-addict    schedule 27.07.2018
comment
Извините за это, обновил.   -  person Dwarrior    schedule 27.07.2018


Ответы (2)


Это должно работать так же, как и для классов Java, потому что нет никакой разницы, о которой должны заботиться загрузчики классов, я делал это много раз. Но возможная проблема заключается в том, что если вы не включите зависимости в arr; это верно как для Java, так и для Scala, но для Scala вам может не хватать scala-library-<version>.jar.

person Alexey Romanov    schedule 27.07.2018
comment
Привет, Алексей, я уже добавил scala-library-2.11.11.jar, и это та же версия в моем проекте scala. - person Dwarrior; 27.07.2018
comment
не могли бы вы поделиться примером кода, чтобы я мог увидеть, что мне не хватает? Это сообщение об ошибке. Я получаю исключение в потоке main java.lang.ClassNotFoundException: com.testing.Test в java.net.URLClassLoader.findClass(URLClassLoader.java:381) в java.lang.ClassLoader.loadClass(ClassLoader.java :424) в sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:338) в java.lang.ClassLoader.loadClass(ClassLoader.java:357) - person Dwarrior; 27.07.2018
comment
Все мои примеры были бы внутри больших проектов и не очень полезны. Вы можете увидеть пример по адресу github.com/scalan/scalan/blob/: это просто classLoader.loadClass как у вас. - person Alexey Romanov; 27.07.2018
comment
Не уверен, что произошло, но теперь он обошел мой код, и теперь он не работает в следующей строке. val myMethod = clazz.getDeclaredMethod(methodName, classOf[String]) . Исключение в потоке main java.lang.IllegalArgumentException: объект не является экземпляром объявляющего класса - person Dwarrior; 27.07.2018
comment
Что-то не так с классом scala или мне нужно использовать объект? - person Dwarrior; 27.07.2018
comment
Я думаю, что нашел решение. val foo = clazz.newInstance() и передача foo в mymethod.invoke(foo) разрешена. Проверю еще раз, не порвется ли. - person Dwarrior; 27.07.2018
comment
Привет, Алексей, Программа работала правильно для одной функции, для нескольких функций в scala - spark это начало выдавать ошибку типа {className}$$anonfun$1, где {className} - фактическое имя класса. - person Dwarrior; 30.07.2018
comment
Похоже проблема с искрой. Я думаю, что метод работает так, как ожидалось. - person Dwarrior; 30.07.2018

Публикация ответа для тех, кто ищет аналогичную проблему. Classloader работает, как и ожидалось, как для scala, так и для java.

Для Java у меня работала просто передача имени метода в method.invoke, тогда как в scala мне приходилось специально создавать объект класса и передавать этот объект в method.invoke. Новое обучение для меня.

person Dwarrior    schedule 30.07.2018