1 ответ
Я нашел ответ. Просмотрев эту статью, я понял, что мне нужен как банка из проекта A, так и commons-lang-2.6.jar в тестовом проекте. Добавление BOTH в путь сборки и экспорт разрешили проблему.
10 май 2013, в 13:02
Поделиться
Ещё вопросы
- JQuery Tabs — ссылка на вкладку из вкладки. Работает в Chrome, а не FF / IE
- 1Выберите 4 строки на основе значения MAX в качестве слайд-шоу
- QT диалог закрыть и удалить
- 1как сделать так, чтобы значение для редактирования текста оставалось на той же странице после выхода из одного занятия
- 2Лучший способ обработки соединения при вызове функции из консольного приложения или объекта SQLCLR с помощью («Context Connection = true»)
- 1Получить привязанный обработчик событий в Tkinter
- 1Сбой для вставки флажков получения неопределенной обратной связи с переменными
- Снимите флажок в angular-метеоре
- Запрос документа Amazon Product JSON
- 1Путь между двумя городами с использованием BFS в Java
- Как я могу вставить новую строку в таблицу, используя Hibernate?
- customClass в Angularjs UIB-DatePicker зависит от обещания
- C ++ Назначить переменную типа A для типа B, которая расширяет A
- 1Применить функцию вдоль оси над двумя массивами — фигуры не выровнены
- Фильтрация результатов из подзапроса в MySql
- Чайлдс шоу, используя при нажатии на родителя
- 1xpage, вызывающий агент Java, терпит неудачу, когда библиотека сценария включена в агент
- 1движок приложения для Android Java: аутентификация пользователей
- 1Неопределенный строковый литерал в коде javascript, и я не уверен насчет кода PHP
- 1Как добавить новое поле в конфигурацию magento?
- 2C # должен ли Singleton содержать статические методы?
- 1Использование G-WAN для веб-сервисов
- 1IllegalMonitorStateException в потоке ожидания уведомить
- 1Android как «заставить» применить макет
- Laravel Lumen + Angular .. Тот же проект или нет?
- 1Spritesheet против карты отдельных спрайтов, производительность Android
- 2конечная точка openid не найдена
- Невозможно связать два контейнера «sidecar» в моем конвейере Jenkins
- Сохранить состояние div в переменную
- Автоматическая прокрутка до каждого элемента или элемента
- Управление ArrayList в jquery и вывод печати в jsp
- 1Сохраняются ли слушатели событий в памяти в Node.js?
- 1Как отобразить изображение base64? URI слишком длинный
- Включение библиотек c ++ в C
- Как добавить данные в элемент
- JQuery не хочет отображать второй параметр атрибута
- 1ionic 3 — внедрить средство выбора даты в листе действий
- 1Как использовать traceit для сообщения о входных переменных функций в трассировке стека
- Расширение и оптимизация jQuery Accordion Menu
- Сравнение ввода пользователя с именами пользователей в базе данных
- Sql полигональный запрос занимает много времени, чтобы выполнить с подзапросом
- Есть ли способ создать схему и таблицы в MySQL Docker без создания нового образа для MySQL?
- Не удалось нарисовать несколько линий на изображении с помощью мыши
- Шрифт Google Oswald не отображается правильно при установке в системе
- Как помешать Гуроби преобразовать Макс в Мин проб?
- 1Модули узла не определены в моем скрипте
- 1Сообщение SOAP, в результате которого «400 неверных запросов»
- 1Получить Procentual Value в PHP
- Невозможно получить правильное значение для клавиш со стрелками
- Обработка данных в реальном времени с помощью angularJs
Создание проекта в Visual Studio 2019
Когда вы запустите Visual Studio 2019, вы должны увидеть диалоговое окно, которое выглядит следующим образом:
Рисунок 2 – Диалоговое окно «Начало работы» Visual Studio 2019
Выберите Создание проекта (Create a new project).
После этого вы увидите диалоговое окно, которое выглядит следующим образом:
Рисунок 3 – Visual Studio 2019: диалоговое окно создания нового проекта
Если вы уже открыли предыдущий проект, вы можете открыть это диалоговое окно через меню Файл (File) → Создать (New) → Проект (Project).
Выберите Мастер классических приложений Windows (Windows Desktop Wizard) и нажмите Далее (Next). Если вы этого не видите, то вы, вероятно, при установке Visual Studio забыли выбрать установку Desktop development with C++. В этом случае вернитесь к уроку «0.6 – Установка интегрированной среды разработки (IDE)» и переустановите Visual Studio, как было показано (примечание: вместо полной переустановки вы можете запустить установщик Visual Studio и изменить существующую установку, чтобы добавить поддержку C++).
Далее вы увидите диалоговое окно, которое выглядит следующим образом:
Рисунок 4 – Диалоговое окно настройки нового проекта Visual Studio 2019
Замените существующее имя проекта на HelloWorld.
Рекомендуется также установить флажок «Поместить решение и проект в одном каталоге» (Place solution and project in the same directory), поскольку это сокращает количество подкаталогов, создаваемых с каждым проектом.
Нажмите Создать (Create), чтобы продолжить.
Наконец, вы увидите последнее диалоговое окно:
Рисунок 5 – Диалоговое окно параметров проекта Visual Studio 2019
Убедитесь, что тип приложения установлен как Консольное приложение (.exe) (Console Application (.exe)), и что параметр Предкомпилированный заголовок (Precompiled Header) не выбран. Затем нажмите ОК.
Вы создали проект! Чтобы продолжить, перейдите в раздел ниже.
В чём причина NoClassDefFoundError в Java?
NoClassDefFoundError в Java происходит тогда, когда виртуальная машина Java во время исполнения кода не может найти определённый класс, который был доступен во время компиляции. Например, если мы вызываем метод из класса или обращаемся к статическому члену класса и этот класс не доступен во время выполнения, то виртуальная машина Java выбрасывает NoClassDefFoundError
Важно понимать, что эта ошибка отличается от исключения ClassNotFoundException, которое происходит при попытке загрузки класса во время выполнения, причём важно, что имя этого класса было определено только во время выполнения, но не во время компиляции кода. Многие Java разработчики путают эти две ошибки и приходят в тупик при попытке разрешить вопрос.
Коротко говоря, NoClassDefFoundError происходит, если класс присутствовал во время компиляции, но не доступен в classpath во время исполнения. Обычно в этом случае вы увидите следующую строку в журнале ошибок:
Exception in thread «main» java.lang.NoClassDefFoundError
Фраза Exception in thread «main» означает, что именно поток «main» не может найти определённый класс. Вместо «main» может быть любой поток. Разница между тем, когда эта ошибка возникает в потоке «main» и в другом потоке в состоит том, что при возникновении в потоке «main» программа останавливается, а при возникновении в ином потоке, напротив, продолжает выполнение после ошибки.
Создание проекта в Code::Blocks
Чтобы создать новый проект, перейдите в меню File (Файл) → New (Новый) → Project (Проект). Появится диалоговое окно, которое выглядит следующим образом:
Рисунок 10 – Code::Blocks. Диалоговое окно создания проекта
Выберите Console application (консольное приложение) и нажмите кнопку Go (перейти/создать).
Если вы видите диалоговое окно мастера консольного приложения, нажмите Next (далее), убедитесь, что выбран C++, и снова нажмите Next.
Теперь вам будет предложено назвать ваш проект. Назовите проект HelloWorld. Вы можете сохранить его где угодно. В Windows мы рекомендуем сохранить его в подкаталоге диска C, например C:\CBProjects.
Рисунок 11 – Code::Blocks. Диалогове окно сохранения проекта
Вы можете увидеть другое диалоговое окно с вопросом, какие конфигурации вы хотите включить. Значения по умолчанию здесь подойдут, поэтому выберите Finish.
Теперь ваш новый проект создан.
В левой части экрана вы должны увидеть окно Management (управление) с выбранной вкладкой Projects (проекты). Внутри этого окна вы увидите папку Workspace с вашим проектом HelloWorld внутри:
Рисунок 12 – Code::Blocks. Workspace
Внутри проекта HelloWorld разверните папку Sources (исходники) и дважды щелкните на «main.cpp». Вы увидите, что для вас уже написана программа hello world!
Замените ее следующим кодом:
Чтобы собрать проект, нажмите Ctrl + F9 или перейдите в меню Build (Сборка) → Build (Сборка). Если всё пойдет хорошо, вы должны увидеть следующее в окне журнала сборки:
Это означает, что компиляция прошла успешно!
Чтобы запустить скомпилированную программу, нажмите Ctrl + F10 или перейдите в меню Build (Сборка) → Run (Запуск). Вы увидите что-то похожее на следующий скриншот:
Рисунок 13 – Запуск программы
Это результат выполнения вашей программы!
Для пользователей Linux
Пользователям Linux до компиляции в Code::Blocks может потребоваться установить дополнительные пакеты. Дополнительные сведения смотрите в инструкциях по установке Code::Blocks в уроке «0.6 – Интегрированная среда разработки (IDE)».
Дополнительные опции
Дополнительные параметры javac -это нестандартные параметры, которые специфичны для текущей реализации компилятора и могут быть изменены в будущем. Поэтому мы не будем подробно рассматривать эти варианты.
Однако есть вариант, который очень полезен и заслуживает упоминания, -Xlint . Для получения полного описания других javac дополнительных опций перейдите по .
Опция -Xlint позволяет нам включать предупреждения во время компиляции . Существует два способа указать этот параметр в командной строке:
- -Xlint – запускает все рекомендуемые предупреждения
- -Xlint:клавиша* – включает определенные предупреждения
Вот некоторые из самых удобных -Xlint клавиш:
- rawtypes – предупреждает об использовании необработанных типов
- unchecked – предупреждает о непроверенных операциях
- static – предупреждает о доступе к статическому члену от члена экземпляра
- cast – предупреждает о ненужных бросках
- serial – предупреждает о том, что сериализуемые классы не имеют serialVersionUID
- fallthrough – предупреждает о провале в операторе switch
Теперь создайте файл с именем xl в tops в каталоге javac-args со следующим содержимым:
-d javac-target -Xlint:rawtypes,unchecked com/baeldung/javac/Data.java
При выполнении этой команды:
javac @javac-args/xlint-ops
мы должны увидеть rawtypes и непроверенные предупреждения:
com/baeldung/javac/Data.java:7: warning: found raw type: ArrayList List textList = new ArrayList(); ^ missing type arguments for generic class ArrayList where E is a type-variable: E extends Object declared in class ArrayList com/baeldung/javac/Data.java:7: warning: unchecked conversion List textList = new ArrayList(); ^ required: List found: ArrayList ...
Пример с несколькими файлами
В уроке «2.6 – Предварительные объявления и определения» мы рассмотрели программу с одним исходным файлом, которая не компилируется:
Когда компилятор достигает вызова функции в строке 5 в функции , он не знает, что такое , потому что мы определили только в строке 9! Нашим решением было либо переупорядочить функции (поместив сначала ), либо использовать для предварительное объявление.
Теперь посмотрим на аналогичную программу из нескольких исходных файлов:
add.cpp:
main.cpp:
Ваш компилятор может решить сначала скомпилировать либо add.cpp, либо main.cpp. В любом случае main.cpp не скомпилируется, что приведет к той же ошибке компилятора, что и в предыдущем примере:
Причина точно такая же: когда компилятор достигает строки 5 файла main.cpp, он не знает, что такое идентификатор .
Помните, что компилятор компилирует каждый файл отдельно. Он не знает о содержимом других исходных файлов и не запоминает что-либо, что он видел из ранее скомпилированных исходных файлов. Таким образом, даже если компилятор, возможно, видел определение функции ранее (если он сначала скомпилировал add.cpp), он этого не запомнил.
Эта ограниченная видимость и короткая память являются преднамеренными, чтобы файлы могли иметь функции или переменные, у которых одинаковые имена, но которые не конфликтуют друг с другом. В следующем уроке мы рассмотрим пример такого конфликта.
Наши варианты решения здесь такие же, как и раньше: поместить определение функции перед функцией или удовлетворить компилятор предварительным объявлением. В этом случае, поскольку функция находится в другом файле, вариант изменения порядка определений не подходит.
Лучшее решение здесь – использовать предварительное объявление:
main.cpp (с предварительным объявлением):
add.cpp (остается прежним):
Теперь, когда компилятор компилирует main.cpp, он будет знать, что такое идентификатор , и будет удовлетворен. Линкер соединит вызов функции в main.cpp с определением функции в add.cpp.
Используя этот метод, мы можем предоставить файлам доступ к функциям, которые находятся в другом файле.
Попробуйте скомпилировать add.cpp и main.cpp с предварительным объявлением. Если вы получили ошибку линкера, убедитесь, что вы правильно добавили add.cpp в свой проект или строку компиляции.
Команда javac
Мы можем указать параметры и исходные файлы при выполнении инструмента javac :
javac
Где обозначает параметры, управляющие операциями инструмента, и указывает один или несколько исходных файлов, которые будут скомпилированы.
Все варианты действительно совершенно необязательны. Исходные файлы могут быть непосредственно указаны в качестве аргументов команды javac или сохранены в файле аргументов, на который ссылается ссылка, как описано ниже
Обратите внимание, что исходные файлы должны быть расположены в иерархии каталогов, соответствующей полным именам типов, которые они содержат
Параметры javac подразделяются на три группы: стандартные, кросс-компиляционные и дополнительные. В этой статье мы сосредоточимся на стандартных и дополнительных опциях.
Параметры кросс-компиляции используются для менее распространенного случая компиляции определений типов в реализации JVM, отличной от среды компилятора, и не будут рассматриваться.
Библиотеки
Разделение объявления класса и его реализации очень распространено в библиотеках, которые используются для расширения возможностей вашей программы. Вы также подключали такие заголовочные файлы из Стандартной библиотеки С++, как iostream, string, vector, array и другие
Обратите внимание, вы не добавляли iostream.cpp, string.cpp, vector.cpp или array.cpp в ваши проекты. Ваша программа нуждается только в объявлениях из заголовочных файлов, чтобы компилятор смог проверить корректность вашего кода в соответствии с правилами синтаксиса языка C++
Однако реализации классов, находящихся в Стандартной библиотеке С++, содержатся в предварительно скомпилированном файле, который добавляется на этапе линкинга. Вы нигде не встречаете этот код.
Вне программ с открытым исходным кодом (где предоставляются оба файла: .h и .cpp), большинство сторонних библиотек предоставляют только заголовочные файлы вместе с предварительно скомпилированным файлом библиотеки. На это есть несколько причин:
На этапе линкинга быстрее будет подключить предварительно скомпилированную библиотеку, чем выполнять перекомпиляцию каждый раз, когда она нужна.
Защита интеллектуальной собственности (создатели не хотят, чтобы другие просто «воровали» их код).
Наличие собственных файлов, разделенных на объявление (файлы .h) и реализацию (файлы .cpp), является не только хорошей формой содержания кода, но и упрощает создание собственных пользовательских библиотек.
2. NoClassDefFoundError caused by an ExceptionInInitializerError
When you see NoClassDefFoundError with
an ExceptionInInitializerError in stacktrace then a dependent class
initialization has failed. NoClassDefFoundError is just a symptom. The actual
issue is ExceptionInInitializerError which we need to find and fix.
Consider the scenario explained in
1.2 above. Suppose there is a static initializer in a ReferenceClass in Reference.jar
and it failed. There would be an ExceptionInInitializerError for this class. Below,
I am manually throwing an exception to explain this:
public class ReferenceClass {
// Static initializer block executed at Class loading time
static {
// Static block code execution…
throw
new Exception(«Throwing error manually»);
}
}
Now if another CallerClass in Caller.jar
is using an object of ReferenceClass it would fail with a NoClassDefFoundError.
public class CallerClass {
public static void main(String[] args) {
try
{
// Create a new instance of Class ReferenceClass
ReferenceClass referenceClass = new ReferenceClass();
} catch (Throwable t) {
t.printStackTrace();
}
}
}
It is tricky to find resolution of
such cases. You need to look at the stacktrace and find out where exactly ExceptionInInitializerError
is thrown. If it’s your code packed into the jar, you can change, recompile and
pack again. If you see this error in any class of library you are using then
you need to check what condition is causing the ExceptionInInitializerError.
Следующие шаги
Этот пример Hello, World является самой простой программой C. Реальные программы выполняют полезные действия и имеют файлы заголовков, дополнительные исходные файлы и ссылки на библиотеки.
Вы можете использовать шаги, описанные в этом пошаговом руководстве для C, для создания собственного кода, чтобы не вводить приведенный пример. Вы также можете выполнить сборку различных примеров кода на C, которые можно найти в других местах. Чтобы скомпилировать программу с дополнительными файлами исходного кода, введите их все в командной строке, например:
Компилятор выдает программу с именем file1.exe. Чтобы изменить имя на program1.exe, добавьте параметр компоновщика /out:
Чтобы автоматически перехватывать другие ошибки программирования, рекомендуется выполнить компиляцию с помощью порога предупреждений /W3 или /W4:
Компилятор cl.exe имеет множество других параметров, которые можно применять для создания, оптимизации, отладки и анализа кода. Чтобы просмотреть краткий список, введите в командной строке разработчика. Можно также выполнять компиляцию и компоновку отдельно и применять параметры компоновщика в более сложных сценариях сборки. Дополнительные сведения о параметрах компилятора и компоновщика и использовании см. в разделе Справочник по построению C/C++.
Для настройки и создания более сложных проектов в командной строке можно использовать NMAKE и файлы makefile либо MSBuild и файлы проекта. Дополнительные сведения об использовании этих средств см. в разделах Справочник по NMAKE и MSBuild.
Языки C и C++ похожи, но имеют различия. Компилятор Microsoft C/C++ (MSVC) использует простое правило для определения языка, используемого при компиляции кода. По умолчанию компилятор MSVC рассматривает все файлы с расширением как исходные коды на языке С, а файлы с расширением как исходные коды на языке С++. Если указан параметр компилятора /TC, компилятор будет рассматривать все файлы как исходные коды на языке С вне зависимости от расширения.
Компилятор MSVC совместим со стандартами ANSI C89 и ISO C99, но не полностью. В большинстве случаев переносимый код на языке C будет компилироваться и выполняться должным образом. Компилятор обеспечивает дополнительную поддержку изменений в ISO C11/C17. Чтобы выполнить компиляцию с поддержкой C11/C17, используйте флаг компилятора или . Для поддержки C11 и C17 требуется Windows SDK 10.0.20201.0 или более поздняя версия. Рекомендуется использовать Windows SDK 10.0.22000.0 или более позднюю версию. Последнюю версию пакета можно скачать на странице Windows SDK. Дополнительные сведения и инструкции по установке и использованию этого пакета SDK для разработки на языке C см. в статье Установка поддержки C11 и C17 в Visual Studio.
Некоторые функции библиотеки и имена функций POSIX являются нерекомендуемыми в компиляторе MSVC. Функции поддерживаются, но предпочтительные имена изменились. Дополнительные сведения см. в статьях Функции безопасности в CRT и Предупреждение компилятора (уровень 3) C4996.
Итак, что я должен определять в файле заголовка, а что в файле .cpp,и что внутри определения класса, а что вне его?
У вас может возникнуть соблазн поместить все определения ваших функций-членов в заголовочный файл внутри класса. Хотя это будет компилироваться, у этого подхода есть несколько недостатков. Во-первых, как упоминалось выше, это загромождает определение вашего класса. Во-вторых, если вы измените что-либо в коде в заголовке, вам придется перекомпилировать каждый файл, который включает этот заголовок. Это может иметь волновой эффект, когда одно незначительное изменение вызывает необходимость перекомпиляции всей программы (что может быть медленным). Если вы измените код в файле .cpp, необходимо будет перекомпилировать только этот файл .cpp!
Поэтому мы рекомендуем следующее:
- классы, используемые только в одном файле, и которые, как правило, нельзя использовать повторно, определяйте непосредственно в том файле .cpp, где они используются;
- классы, используемые в нескольких файлах или предназначенные для повторного использования, определяйте в файле .h с тем же именем, что и класс;
- тривиальные функции-члены (тривиальные конструкторы или деструкторы, функции доступа и т.д.) могут быть определены внутри класса;
- нетривиальные функции-члены должны быть определены в файле .cpp с тем же именем, что и класс.
В будущих уроках большинство наших классов будет определено в файле .cpp, а все функции будут реализованы непосредственно в определении класса. Это сделано для удобства и для краткости примеров. В реальных проектах классы гораздо чаще помещаются в их собственные исходные и заголовочные файлы, и вы должны привыкнуть к этому.
Создание файла исходного кода на языке C и его компиляция из командной строки
-
В окне командной строки разработчика введите команду , чтобы изменить текущий рабочий каталог на корень диска C:. Затем введите , чтобы создать каталог, и введите , чтобы перейти к этому каталогу. В этом каталоге будут находиться исходный файл и скомпилированная программа.
-
В командной строке разработчика введите команду . в появившемся диалоговом окне оповещения Блокнот выберите да , чтобы создать новый файл в рабочем каталоге.
-
В окне блокнота введите следующие строки кода:
-
в строке меню Блокнот выберите файлсохранить , чтобы сохранить его в рабочем каталоге.
-
Вернитесь к окну командной строки разработчика. Введите в командной строке, чтобы получить список содержимого каталога . Вы увидите исходный файл в списке каталогов, который выглядит примерно так:
Даты и некоторые другие данные будут отличаться на вашем компьютере. Если вы не видите файл исходного кода , убедитесь в том, что вы открыли созданный каталог и сохранили исходный файл в нем в блокноте. Также убедитесь, что исходный код был сохранен с расширением имени файла , а не .
-
Чтобы скомпилировать программу, в командной строке разработчика введите .
Имя исполняемой программы (hello.exe) отображается в информации, выводимой компилятором.
Примечание
Если вы получаете сообщение об ошибке, например «cl не распознается как внутренняя или внешняя команда, исполняемая программа или пакетный файл», ошибке C1034 или LNK1104, командная строка разработчика настроена неправильно. Чтобы получить сведения о том, как устранить эту проблему, вернитесь к разделу Открыть командную строку разработчика.
Если вы получаете другое сообщение об ошибке или предупреждение компилятора или компоновщика, проверьте исходный код, исправьте ошибки, сохраните его и снова запустите компилятор. Для получения сведений о конкретных ошибках введите номер ошибки в поле поиска вверху этой страницы.
-
Чтобы запустить программу, в командной строке введите .
Программа выводит следующий текст и затем закрывается:
Поздравляем! Вы скомпилировали и запустили программу на C с помощью командной строки.
Java ClassNotFoundException Example
Let’s look at a simple example where we will get ClassNotFoundException.
package com.journaldev.exceptions;public class DataTest { public static void main(String[] args) { try { Class.forName(“com.journaldev.MyInvisibleClass”); ClassLoader.getSystemClassLoader().loadClass(“com.journaldev.MyInvisibleClass”); ClassLoader.getPlatformClassLoader().loadClass(“com.journaldev.MyInvisibleClass”); } catch (ClassNotFoundException e) { e.printStackTrace(); } }}
Note that com.journaldev.MyInvisibleClass doesn’t exist, so When we execute above program, we get following exception stack trace.
java.lang.ClassNotFoundException: com.journaldev.MyInvisibleClass at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:582) at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:185) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:496) at java.base/java.lang.Class.forName0(Native Method) at java.base/java.lang.Class.forName(Class.java:292) at com.journaldev.exceptions.DataTest.main(DataTest.java:7)
In above example, all the three statements will throw java.lang.ClassNotFoundException.
Разбираемся с причинами noclassdeffounderror в Java
NoClassDefFoundError в Java возникает, когда виртуальная машина Java не может найти определенный класс во время выполнения, который был доступен во время компиляции.
Например, если у нас есть вызов метода из класса или доступ к любому статическому члену класса, и этот класс недоступен во время выполнения, JVM сгенерирует NoClassDefFoundError.
NoClassDefFoundError возникнет, если класс присутствовал во время компиляции, но не был доступен в java classpath во время выполнения. Обычно появляется такая ошибка:
Exception in thread "main" java.lang.NoClassDefFoundError
Разница между java.lang.NoClassDefFoundError и ClassNotFoundException в Java
java.lang.ClassNotFoundException и java.lang.NoClassDefFoundError оба связаны с Java Classpath, и они полностью отличаются друг от друга.
ClassNotFoundException возникает, когда JVM пытается загрузить класс во время выполнения, т.е. вы даете имя класса во время выполнения, а затем JVM пытается загрузить его, и если этот класс не найден, он генерирует исключение java.lang.ClassNotFoundException.
Тогда как в случае NoClassDefFoundError проблемный класс присутствовал во время компиляции, и поэтому программа успешно скомпилирована, но не доступна во время выполнения по любой причине.
Приступим к решению ошибки java.lang.NoClassDefFoundError.
Нам нужно добавить NoClassDefFoundError в Classpath или проверить, почему он не доступен в Classpath. Там может быть несколько причин, таких как:
- Класс недоступен в Java Classpath.
- Возможно, вы запускаете вашу программу с помощью jar, а класс не определен в атрибуте ClassPath.
- Любой сценарий запуска переопределяет переменную среды Classpath. Поскольку NoClassDefFoundError является подклассом java.lang.LinkageError, он также может появиться, если библиотека может быть недоступна.
- Проверьте наличие java.lang.ExceptionInInitializerError в файле журнала. NoClassDefFoundError из-за сбоя инициализации встречается довольно часто.
- Если вы работаете в среде J2EE, то видимость Class среди нескольких Classloader также может вызвать java.lang.NoClassDefFoundError.
Примеры
- Простой пример NoClassDefFoundError – класс принадлежит отсутствующему файлу JAR, или JAR не был добавлен в путь к классам, или имя jar было изменено кем-то.
- Класс не находится в Classpath, нет способа узнать это, но вы можете просто посмотреть в System.getproperty (“java.classpath”), и он напечатает classpath оттуда, где можно получить представление о фактическом пути к классам во время выполнения.
- Просто попробуйте запустить явно -classpath с тем классом, который, по вашему мнению, будет работать, и если он работает, это верный признак того – что-то переопределяет java classpath.
1. NoClassDefFoundError Caused By ClassNotFoundException
1.1Jar file(s)
missing from classpath
This is the most comman case of NoClassDefFoundError.
Take a close look at the stacktrace and figure out which class is giving a ClassNotFoundException.
Now search for the jar which
contains that class. If you are using eclipse you can search using the class
name in pattern *.jar. Or you can go online and check which all jars contain
that class.
For
example refer the stacktrace below:
Exception
in thread «main» java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
at org.springframework.context.support.AbstractApplicationContext.<init>(AbstractApplicationContext.java:119)
at org.springframework.context.support.AbstractXmlApplicationContext.<init>(AbstractXmlApplicationContext.java:55)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:77)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:65)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:56)
at com.client.StoryReader.main(StoryReader.java:15)
Caused by:
java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native
Method)
at java.net.URLClassLoader.findClass(Unknown
Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown
Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClassInternal(Unknown
Source)
… 6 more
The above shows that the class org.apache.commons.logging.LogFactory
is missing in classpath. When you search for it, you will find that commons-logging.jar.
Now check if this jar is present in classpath. If yes, verify the jar name and
path, if not adding it would resolve the
error.
1.2Some
dependent jar is missing which not allowing the class constructor to initialize
the class object.
The NoClassDefFoundError during static initialization
The can also be thrown during the static initialization of a class. If an exception occurs during the loading and initialization of a class and the definition of another class depends on the former class, then an is thrown.
The following class reproduces the aforementioned problem:
StaticInitializationErrorExample.java:
import java.util.List; import java.util.ArrayList; import java.util.Random; public class StaticInitializationErrorExample { private final static int TOTAL_RECORDS = 100; public static void main(String args[]) { try{ List records = new ArrayList(TOTAL_RECORDS); for(int i=1; i < TOTAL_RECORDS; ++i) records.add(new Record(i)); } catch(Throwable t) { t.printStackTrace(); throw t; } } } class Record { private static Integer ID = getRandomInteger(); public Record(Integer Id){ this.ID = Id; } private static Integer getRandomInteger() { throw new RuntimeException("The method is not implemented..."); //return new Random.nextInt(); } }
In this example, we defined a class with a static field, called . When, the class is about to get loaded and initialized, the method throws a and thus, the method that is static and requires the definition of the class throws an .
A sample execution is shown below:
java.lang.ExceptionInInitializerError at StaticInitializationErrorExample.main(StaticInitializationErrorExample.java:14) Caused by: java.lang.RuntimeException: The method is not implemented... at Record.getRandomInteger(StaticInitializationErrorExample.java:31) at Record.(StaticInitializationErrorExample.java:24) ... 1 more Exception in thread "main" java.lang.ExceptionInInitializerError at StaticInitializationErrorExample.main(StaticInitializationErrorExample.java:14) Caused by: java.lang.RuntimeException: The method is not implemented... at Record.getRandomInteger(StaticInitializationErrorExample.java:31) at Record.(StaticInitializationErrorExample.java:24) ... 1 more
Если компиляция завершилась ошибкой
Ничего страшного, сделайте глубокий вдох. Вероятно, мы сможем это исправить.
Сначала посмотрите на сообщение об ошибке, которое вам выдал компилятор. Чаще всего оно будет содержать номер строки, указывающий, какая строка содержала ошибку. Изучите и эту строку, и строки вокруг нее и убедитесь, что нет опечаток или орфографических ошибок. Также убедитесь, что вы не скопировали в код номера строк.
Во-вторых, посмотрите вопросы и ответы в уроке «0.8 – Несколько распространенных проблем C++», поскольку ваша проблема может быть там освещена.
В-третьих, прочтите комментарии ниже – кто-то мог столкнуться с той же проблемой.
Наконец, если всё вышеперечисленное не помогло, попробуйте поискать сообщение об ошибке в Google. Скорее всего, кто-то уже сталкивался с этим раньше и придумал, как это исправить.
Заключение
Возможно, у вас возникнет соблазн поместить все определения методов класса в заголовочный файл внутри тела класса. Хотя это скомпилируется, но здесь есть несколько нюансов:
Во-первых, как упоминалось выше, это приведет к загромождению определения вашего класса.
Во-вторых, функции, определенные внутри класса, являются неявно встроенными. Большие функции, которые вызываются из многих файлов, могут способствовать, таким образом, «раздуванию» вашего кода.
В-третьих, если вы измените что-либо в заголовочном файле, то вам нужно будет перекомпилировать каждый файл, содержащий этот заголовок. Это может иметь «эффект бабочки», когда одно незначительное изменение заставит перекомпилировать всю программу (что может быть достаточно медленно и долго). Если же вы изменили код в файле .cpp, то вам необходимо перекомпилировать только этот файл .cpp!
Поэтому рекомендуется следующее:
Классы, используемые только в одном файле, и которые повторно не используются, определяйте непосредственно в файле .cpp, где они используются.
Классы, используемые в нескольких файлах или предназначенные для повторного использования, определяйте в заголовочном файле с тем же именем, что у класса.
Тривиальные методы (обычные конструкторы или деструкторы, функции доступа и т.д.) определяйте внутри тела класса.
Нетривиальные методы определяйте в файле .cpp с тем же именем, что у класса.
На следующих уроках большинство наших классов будут определены в файле .cpp со всеми методами, реализованными непосредственно в теле класса. Это делается для удобства и лаконичности примеров. В реальных проектах лучше, когда классы помещаются в отдельные файлы .cpp и .h.