Scala — Как использовать Java Singleton Object

Я успешно использовал существующие проекты Java для своего проекта Scala, но столкнулся с NoClassDefFoundError при использовании синглтона Java:

public class SpecificUser extends BasicUser {

    private static SpecificUser INSTANCE = new SpecificUser();

    protected SpecificUser() { }

    public static SpecificUser getInstance() {
        return INSTANCE;
    }
    ...
}

Вот точная ошибка:

play.api.Application$$anon$1: Execution exception[[RuntimeException: java.lang.NoClassDefFoundError: Could not initialize class SpecificUser]]
    at play.api.Application$class.handleError(Application.scala:296) ~[play_2.11-2.3.5.jar:2.3.5]
    at play.api.DefaultApplication.handleError(Application.scala:402) [play_2.11-2.3.5.jar:2.3.5]
    at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$14$$anonfun$apply$1.applyOrElse(PlayDefaultUpstreamHandler.scala:205) [play_2.11-2.3.5.jar:2.3.5]
    at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$14$$anonfun$apply$1.applyOrElse(PlayDefaultUpstreamHandler.scala:202) [play_2.11-2.3.5.jar:2.3.5]
    at scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:36) [scala-library-2.11.1.jar:na]
Caused by: java.lang.RuntimeException: java.lang.NoClassDefFoundError: Could not initialize class SpecificUser
    at play.api.mvc.ActionBuilder$$anon$1.apply(Action.scala:523) ~[play_2.11-2.3.5.jar:2.3.5]
    at play.api.mvc.Action$$anonfun$apply$1$$anonfun$apply$4$$anonfun$apply$5.apply(Action.scala:130) ~[play_2.11-2.3.5.jar:2.3.5]
    at play.api.mvc.Action$$anonfun$apply$1$$anonfun$apply$4$$anonfun$apply$5.apply(Action.scala:130) ~[play_2.11-2.3.5.jar:2.3.5]
    at play.utils.Threads$.withContextClassLoader(Threads.scala:21) ~[play_2.11-2.3.5.jar:2.3.5]
    at play.api.mvc.Action$$anonfun$apply$1$$anonfun$apply$4.apply(Action.scala:129) ~[play_2.11-2.3.5.jar:2.3.5]
Caused by: java.lang.NoClassDefFoundError: Could not initialize class SpecificUser
    at controllers.UsersController$$anonfun$usersDatatable$1.apply(UsersController.scala:36) ~[classes/:na]
    at controllers.UsersController$$anonfun$usersDatatable$1.apply(UsersController.scala:34) ~[classes/:na]
    at controllers.security.Authentication$$anonfun$AuthenticatedAction$1.apply(AuthenticatedController.scala:21) ~[classes/:na]
    at controllers.security.Authentication$$anonfun$AuthenticatedAction$1.apply(AuthenticatedController.scala:19) ~[classes/:na]
    at play.api.mvc.ActionBuilder$$anonfun$apply$16.apply(Action.scala:433) ~[play_2.11-2.3.5.jar:2.3.5]

Эти вопросы могли бы помочь определить, что доступ к статическим методам может быть недоступен в Scala, но не помогли определить работающее решение:

https://stackoverflow.com/a/4448069/1359765

https://stackoverflow.com/a/21303729/1359765

Как мне использовать мой одноэлементный объект в Scala?

ОБНОВЛЕНИЕ

Я создал синглтон в проекте зависимостей java, который я использую, и он работал нормально. Проблема в том, что синглтон наследуется от BasicUser, который находится в другом проекте зависимостей Java, который я использую.


person j will    schedule 10.11.2014    source источник
comment
Какова точная ошибка, а также как вы компилируете и запускаете проект? Это смешанный проект Java/Scala или код Java находится в зависимости?   -  person drexin    schedule 10.11.2014
comment
Собираю и запускаю проект с активатором. Это не смешанный проект java/scala, проект java используется как зависимость для проекта Scala Play.   -  person j will    schedule 10.11.2014
comment
Попробуйте использовать ту же конфигурацию из класса java. Проблема в том, что класс SpecificUser имеет исключение в статическом блоке (в суперклассе). Проверьте все неперехваченные исключения в режиме отладки.   -  person Andrzej Jozwik    schedule 11.11.2014
comment
@AndrzejJozwik - Что вы имеете в виду, пытаясь использовать ту же конфигурацию из класса Java? Я использую класс java с его исходной конфигурацией. Я пробовал проверять необработанные исключения в режиме отладки, но проблема в том, что когда я пытаюсь вмешаться и использовать метод getInstance(), отладчик переходит к файлам классов scala, таким как Action.scala, а затем воспроизводит потоки.   -  person j will    schedule 12.11.2014
comment
@jwill Класс загружается в виртуальную машину, если инициализация всех статических блоков завершилась успешно. Если хотя бы один не удался - класс не загружается.   -  person Andrzej Jozwik    schedule 19.12.2014
comment
Возможно, вам следует переключиться на Spring и использовать его внедрение зависимостей. Просто мысль   -  person jlars62    schedule 01.04.2015


Ответы (1)


Ошибка NoClassDefFoundError может возникнуть, если класс-нарушитель имеет статические поля, инициализация которых завершается сбоем с исключением. Проблема при поиске заключается в том, что исключение, вызывающее сбой инициализации класса, не отображается ни в трассировке стека, ни в журнале. В этом случае помогает, если инициализация всех статических полей перенесена в статический инициализатор. В этом случае вы получите, по крайней мере, трассировку стека, показывающую оскорбительное поле. т.е. вместо

class A {
  static B b = new B(....);
}

ты пишешь

class A {
    static B b;
    static {
        b=new B(...);
    }
}
person Wolfgang Liebich    schedule 30.09.2015