Java.lang.NoClassDefFoundError: Не удалось инициализировать класс XXX

public class PropHolder {
  public static Properties prop;

  static {
    //code for loading properties from file
  }
}

// Referencing the class somewhere else:
Properties prop = PropHolder.prop;

class PropHolder - мой собственный класс. Класс находится в том же файле JAR основного класса. Так что это не должно потому, что какой-либо JAR отсутствует в пути к классам.

Когда я смотрю в файл JAR на jar tf myjarfile, я вижу там PropHolder.class.

Btw: код работает нормально на моей локальной машине. Но работать не удалось, когда я развертываю его с помощью некоторого script на сервере Linux. Поэтому я думаю, что это не проблема кода. Но почему-то. процесс развертывания очень трудно отслеживать.

В чем может быть проблема?

Ответ 1

Лучше всего, здесь есть проблема:

static {
    //code for loading properties from file
}

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

Либо это, либо это произошло при создании статической переменной PropHolder.prop.

Ответ 2

Вы получаете java.lang.NoClassDefFoundError, который НЕ означает, что ваш класс отсутствует (в этом случае вы получите java.lang.ClassNotFoundException). ClassLoader столкнулся с ошибкой при чтении определения класса при попытке прочитать класс.

Поместите попытку/улов внутри своего статического инициализатора и посмотрите на исключение. Если вы читаете некоторые файлы там и отличается от своей локальной среды, это, скорее всего, причина проблемы (возможно, файл не может быть найден, никаких разрешений и т.д.).

Ответ 3

NoClassDefFoundError не дает большой информации о том, что пошло не так внутри статического блока. Хорошая практика всегда иметь такой блок внутри статического {...} кода инициализации:

static {
  try {

    ... your init code here

  } catch (Throwable t) {
    LOG.error("Failure during static initialization", t);
    throw t;
  }
}

Ответ 4

У меня было то же исключение, вот как я решил проблему:

Предпосылки:

  • Класс Junit (и тест), который расширил другой класс.

  • ApplicationContext инициализируется с помощью spring, который инициализирует проект.

  • Контекст приложения был инициализирован в методе @Before

Решение:

Инициализировать контекст приложения из метода @BeforeClass, поскольку родительский класс также потребовал некоторые классы, которые были инициализированы из контекста приложения.

Надеюсь, это поможет.

Ответ 5

Как упоминалось выше, это может быть несколько вещей. В моем случае у меня была статически инициализированная переменная, которая полагалась на отсутствующую запись в моем файле свойств. Добавлена ​​отсутствующая запись в файл свойств, и проблема была решена.

Ответ 6

У меня было то же исключение - но только во время работы в режиме отладки, Вот как я решил проблему (через 3 дня): в build.gradle у меня было: "multiDexEnabled true" установлено в разделе defaultConfig.

        defaultConfig {
    applicationId "com.xxx.yyy"
    minSdkVersion 15
    targetSdkVersion 28
    versionCode 5123
    versionName "5123"
    // Enabling multidex support.
    multiDexEnabled true
}

но, видимо, этого было недостаточно. но когда я изменился:

public class MyAppClass  extends Application 

в:

public class MyAppClass  extends MultiDexApplication 

это решило это. надеюсь, это поможет кому-то

Ответ 7

Всего несколько дней назад я встретил тот же вопрос, что и ваш. Весь код хорошо работает на моей локальной машине, но получается ошибка (noclassdeffound & initialize). Поэтому я отправляю свое решение, но я не знаю, почему, я просто выдвигаю возможность. Я надеюсь, что кто-то знает, это объяснит это. @John Vint Во-первых, я покажу вам свою проблему. Мой код имеет статическую переменную и статический блок. Когда я впервые встретил эту проблему, я попробовал решение Джона Винта и попытался поймать исключение. Однако я ничего не поймал. Поэтому я подумал, что это потому, что статическая переменная (но теперь я знаю, что это одно и то же) и до сих пор ничего не нашел. Итак, я пытаюсь найти разницу между машиной Linux и моим компьютером. Затем я обнаружил, что эта проблема возникает только тогда, когда несколько потоков выполняются в одном процессе (кстати, у Linux-машины есть двойные ядра и двойные процессы). Это означает, что если в одном процессе выполняются две задачи (оба используют код с статическим блоком или переменными), это происходит неправильно, но если они работают в разных процессах, то оба они в порядке. На машине Linux я использую

mvn -U clean  test -Dtest=path 

для запуска задачи и потому, что моя статическая переменная заключается в том, чтобы запустить контейнер (или, возможно, вы инициализируете новый загрузчик классов), поэтому он останется до остановки jvm, а jvm остановится только тогда, когда все задачи в одном процессе прекратятся, Каждая задача запускает новый контейнер (или загрузчик классов), и это сбивает jvm. В результате происходит ошибка. Итак, как его решить? Мое решение состоит в том, чтобы добавить новую команду в команду maven и сделать каждую задачу в том же контейнере.

-Dxxx.version=xxxxx #sorry can't post more

Возможно, вы уже решили эту проблему, но все же надеетесь, что это поможет другим, кто встречает ту же проблему.

Ответ 8

Если вы работаете над проектом Android, убедитесь, что вы не вызываете никаких статических методов на каких-либо Android-классах. Я использую только JUnit + Mockito, поэтому, возможно, некоторые другие фреймворки могут помочь вам избежать проблемы в целом, я не уверен.

Моя проблема вызывала Uri.parse(uriString) как часть статического инициализатора для unit test. Класс Uri - это Android API, поэтому конструктор unit test не смог его найти. Я изменил это значение на null, и все вернулось к нормальному.

Ответ 9

У меня были те же проблемы:java.lang.NoClassDefFoundError: Не удалось инициализировать класс com.xxx.HttpUtils

static {
    //code for loading properties from file
}

это проблема среды. Это означает, что свойства в application.yml неверны или пусты!