Проблемы библиотеки Java и пути к классам - PullRequest
0 голосов
/ 12 ноября 2009

Быстрый личный опыт: несколько месяцев назад меня наняли в качестве единственного разработчика .NET (C #) в компании, чьи другие разработчики - разработчики php. Через неделю после работы мне сказали, что они хотят перейти на Java вместо .NET. Не идеальная ситуация, но я пытаюсь заставить ее работать.

Не думаю, что понимаю связь между библиотекой проекта и путем к классам. Я использую NetBeans 6.7.1 для разработки. Мой текущий проект заключается в создании приложения, которое будет обновлять несколько торговых источников (eBay, Amazon и т. Д.). Я создал проект библиотеки классов, который обрабатывает планирование этих обновлений. Мы назовем это Обновление.

Я нахожусь в процессе создания проектов библиотеки классов для различных источников (например, eBay). Я добавил проект ebay в проект обновления в виде библиотеки. В IDE есть поле с надписью «Построить проекты по пути к классам», которое отмечено.

Наконец, сейчас у меня есть небольшое консольное приложение, в котором проект Update упоминается как библиотека (так что в проекте ebay теперь 2 библиотеки) точно таким же образом. Работает с кодом в проекте обновления.

Это работает нормально, пока я не получу экземпляр класса (из проекта Update через консольное приложение), который находится в проекте ebay. В этот момент я получаю

Exception in thread "main"
java.lang.NoClassDefFoundError

что составляет

 Caused by: java.lang.ClassNotFoundException
  at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
  at java.security.AccessController.doPrivileged(Native Method)
  at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
  at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
  at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
  at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
  at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)

Все эти проекты работают нормально, но это исключение времени выполнения убивает меня. Я не знаю, действительно ли я понимаю, что делает добавление библиотеки в проект, и есть ли что-то еще, что мне нужно сделать, чтобы сделать класс доступным. Я привык к тому, что я могу добавить ссылку на DLL и быть готовым к работе. Я не понимаю, почему я не получаю никаких ошибок компилятора или сборки, но я получаю ошибки времени выполнения о доступности. Я предполагаю, что classpath - это недостающий фрагмент, который я не очень хорошо понимаю, хотя полагаю, что эта проблема может быть связана с чем-то другим.

Ответы [ 5 ]

3 голосов
/ 12 ноября 2009

Я настоятельно рекомендую выбрать Core Java, тома 1 и 2. Они должны быть прочитаны для разработчиков Java, которые хотят понять внутреннюю часть языка, такого как ClassLoader. По крайней мере, читайте о загрузке классов.

Чтобы ответить на ваш вопрос, в проекте обновления должны быть созданы файлы .class или jar. Вам нужно указать расположение файлов класса или jar в вашем пути к классам для проекта, из которого вы ссылаетесь на них. В зависимости от вашей IDE, наличие ссылки на проект может дать вам только доступ к источнику для компиляции.

3 голосов
/ 12 ноября 2009

Вам необходимо отделить концепции Java от концепций, специфичных для IDE. Я рекомендую пройти простой Java-учебник, используя текстовый редактор и командную оболочку, прежде чем переходить в NetBeans.

Библиотека и Проект - это особые термины NetBeans. Я не пользователь NetBeans, поэтому я не буду пытаться угадать, что это такое, хотя у меня есть некоторые догадки, но я скажу, что их конфигурация, скорее всего, повлияет на среду компиляции.

Classpath - это базовая концепция Java. Вы должны указать пути ко всем вашим классам (или jar-файлам, которые содержат эти классы) для команды java во время выполнения, чтобы она могла загружать эти классы. (Вам также нужно сделать то же самое с командой javac во время компиляции для классов, на которые вы ссылаетесь, но не компилируете в данный момент).

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

2 голосов
/ 12 ноября 2009

В Java, в отличие от C #, вам необходимо явно добавить пути классов к проекту. Я использую eclipse, и мне пришлось сделать это, чтобы загрузить некоторые из указанных файлов jar.

1 голос
/ 12 ноября 2009
Exception in thread "main"
java.lang.NoClassDefFoundError

Имя класса отсутствует в сообщении об ошибке, но давайте предположим, что это сам класс, для которого вы хотите выполнить метод main. В этом случае это просто означает, что Java не может найти определенный класс в пути к классам во время выполнения.

Чтобы это исправить, вам нужно cd к корню пакета, в котором находится класс, а затем повторно выполнить команду java следующим образом:

java -cp . com.example.MainClass

Здесь аргумент -cp указывает путь к классу. Он имеет только значение ., что означает, что текущий рабочий каталог должен быть взят в classpath (который обычно является регистром по умолчанию, но лучше безопасен, чем ничего).

В качестве альтернативы вы можете указать его полный путь в аргументе -cp, чтобы вы могли выполнить его из любого места, например ::

java -cp /path/to/package/root com.example.MainClass

Еще одна альтернатива, которая чаще всего встречается в руководствах для начинающих, но обычно не используется профессионалами, - это определение переменной среды %CLASSPATH%, в которой в аргументе -cp указано именно то значение, которое вы хотели бы использовать. Затем команда java выполнит поиск (если вы не используете один из аргументов -cp, -classpath или -jar).

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

Если, например, у вас есть файл JAR или другая папка корневого пакета с классами, которые вы хотите использовать в своей программе, вам нужно добавить их в путь к классам. В Windows в качестве разделителя используется точка с запятой ;, а в Linux - :. Далее, когда путь содержит пробелы, вам нужно заключить в кавычки конкретный путь. Вот пример Windows:

java -cp .;/path/to/package/root;"/spacy path/to/file.jar" com.example.MainClass

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

1 голос
/ 12 ноября 2009

Решение, которое я нашел на данный момент:

Я ожидал, что ссылки из вложенных библиотек "всплывают". Это очевидно не работает для classpath. Моя структура была в основном:

A имеет ссылку на B имеет ссылку на C

Когда я запускал A, он работал нормально, пока не добрался до чего-то в C. Что я сделал, так это дал A прямую ссылку на C, добавив его в качестве библиотеки в проект. По результатам некоторых быстрых поисков в Google это выглядит так, как если бы вы добавляли путь к классам в проект в NetBeans.

Мне это кажется немного грязным, и, может быть, есть лучший способ сделать это, но это решило мои проблемы на данный момент. Спасибо всем, кто ответил - хотя никто точно не решил мою конкретную проблему (вы, ребята, добрались до меня примерно на 95% пути), они подтвердили мои мысли и позволили мне выяснить, какой последний кусочек можно было решить.

...