Ява.ленг.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 отсутствует в classpath.



когда я смотрю в файл JAR по jar tf myjarfile Я вижу PropHolder.class в списке есть.



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



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

729   7  

7 ответов:

мой лучший выбор заключается в том, что здесь есть проблема:

static {
    //code for loading properties from file
}

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

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

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

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

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

static {
  try {

    ... your init code here

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

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

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

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

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

  3. контекст приложения был инициализирован в @Before method

устранение:

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

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

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

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

mvn -U clean  test -Dtest=path 

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

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

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

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

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

Comments

    Ничего не найдено.