Scala объект борется с Java Class.newInstance () - PullRequest
0 голосов
/ 13 марта 2012

ОБНОВЛЕНИЕ:

Я несколько решил проблему.На всякий случай, если кто-то запускает ту же проблему, вот самое простое решение: Глядя на исходный код MTApplcation, я обнаружил, что метод initialize() может быть перегружен, принимая параметр String для имени класса для создания экземпляра.Поэтому, если я создаю отдельный класс, который расширяет MTApplication и передает его имя, все работает правильно.

END OF UPDATE

У меня возникла ситуация в Scala при попыткеиспользовать библиотеку Java (MT4j, которая основана на обработке).Библиотека хочет создать экземпляр основного класса приложения (класс вызывающего):

  Class<?> c = Thread.currentThread().getContextClassLoader().loadClass(name);
  applet = (PApplet) c.newInstance();

Чтобы ссылаться на него позже, он работает.

Однако, это не удается, потому что яПредположим, основной класс Scala - это не класс, а объект, и из-за структуры библиотеки необходимо вызвать статический метод initialize() основного класса библиотеки MTApplication.В Java статические поля расположены в классах, а в Scala - в объектах.Таким образом, невозможно создать экземпляр объекта и библиотека не работает.В отличие от MT4j, сама обработка не вызывает статические методы при запуске и успешно проходит этот этап.

Если я просто создаю класс-компаньон, все работает нормально, за исключением того, что класс-компаньон не инициализирует свои поля, поскольку статический метод initialize() вызывается в объекте-компаньоне, экземпляр класса просто становится мертвым ибиблиотека становится непригодной для использования.

По крайней мере, я так понимаю эту проблему.

Я получаю эту ошибку:

Exception in thread "main" java.lang.RuntimeException: java.lang.IllegalAccessException: Class processing.core.PApplet can not access a member of class main.Main$ with modifiers "private"
    at processing.core.PApplet.runSketch(PApplet.java:9103)
    at processing.core.PApplet.main(PApplet.java:9292)
    at org.mt4j.MTApplication.initialize(MTApplication.java:311)
    at org.mt4j.MTApplication.initialize(MTApplication.java:263)
    at org.mt4j.MTApplication.initialize(MTApplication.java:254)
    at main.Main$.main(Main.scala:26)
    at main.Main.main(Main.scala)

Мне трудно объяснить также, потому чтоЯ не до конца понимаю, что здесь происходит.Но любой, у кого есть эти библиотеки, может воспроизвести ситуацию за пару минут, пытаясь запустить основной класс.

Абстрактный метод startUp(), который должен быть реализован для запуска приложения, заставляет все выглядеть еще более печальным,Он инициализирует объект, но библиотека пытается работать с экземпляром класса-компаньона, который не инициализируется, поскольку в Scala метод принадлежит объекту.

Мой код:

object Main extends MTApplication {

    def main(args: Array[String]) {
        MTApplication.initialize()
        new Main().startUp()
    }

    //this method is abstarct so it MUST be implemented,
    override def startUp(){ 
    }

}

class Main extends MTApplication {

    override def startUp(){
       //startup here
    }
}

Извините, если мои объяснения расплывчаты, я просто не понимаю все это полностью.Вероятно, для понимания проще повторить эксперимент с библиотекой MT4j с обработкой исходного кода вместо предварительно связанного с ним «core.jar», чтобы увидеть, что происходит внутри.У кого-нибудь есть идеи по поводу любого обходного пути здесь?

1 Ответ

0 голосов
/ 01 апреля 2012

Проблема решена. Вот решение:

object Main {

    var current: MainC = _

    def main(args: Array[String]) {
        MTApplication.initialize("org.mttablescreen.main.MainC")
    }

}

class MainC extends MTApplication {

    //cons
    Main.current = this

    //cons ends

    override def startUp(){
        prepare
    }

    def prepare () {...}
}
...