Почему мой класс не может быть запущен после объявления пакета и не может быть найден другим классом в том же пакете/папке?

У меня проблемы с пониманием того, как работают пакеты. Не использую никакую IDE.

У меня есть следующая структура папок: ~/dropbox/api/данные

Внутри папки данных находятся (только) Producer.java, Consumer.java.

api
├── data
     ├── Consumer.java
     ├── Producer.java
     └── Producer.class
package data;

public class Producer {
   
   public static void main(String[] args) {
      //do some production
   }

   public static Producer getProducer() {
      //call constructor and return instance
   }
}
----------------
package data;

public class Consumer {

   public static void main(String[] args) {
      Producer worker = getProducer();
   }

}

Я cd в папку данных и javac Producer.java скомпилирую Producer.class в той же папке. Затем, когда я запускаю java Producer, я получаю сообщение об ошибке: не удалось найти или загрузить основной класс Producer. Вызвано: java.lang.NoClassDefFoundError: Producer (неправильное имя: data/Producer).

Та же ошибка, когда я попробовал java Producer и java data.Producer из родительской папки api и java data.Producer в папке data.

  1. Что здесь не так? Если я удалю package data;, он компилируется (javac) и нормально запускается (java) в папке данных.

Кроме того, когда я попробовал javac Consumer.java, я получил ошибку: не могу найти производителя символа. Они находятся в одной папке и объявлены в одном пакете.

  1. Что здесь не так?
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
60
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Команда java требует, чтобы вы указали полное имя класса. Итак, java Producer никогда не сработает; вы должны ввести java data.Producer.

Но это не все.

Пакет следует реж. Итак, когда вы вводите java data.Producer так, как необходимо, Java пытается загрузить data/Producer.class из каждой записи в пути к классам. По умолчанию текущий каталог находится в пути к классам, но если вы возились, например. переменная среды CLASSPATH может быть не так. Чтобы убедиться, что проблема не в этом, java -cp . data.Producer.

Та же ошибка, когда я попробовал Java Producer и Java data.Producer из родительской папки API,

Нет, ты там как-то напутал. java data.Producer из папки API будет работать. На всякий случай попробуйте java -cp . data.Producer (и если это сработает, исправьте все, что вы напутали, с помощью переменной CLASSPATH. Или просто привыкните к этому, это неплохая идея).

Кроме того, когда я попробовал javac Consumer.java, я получаю сообщение об ошибке: не могу найти производителя символа.

Та же проблема, вам нужно запустить javac data/Consumer.java из каталога API.

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

Я добавил скриншот. Структура папок ibapi/historicalData, в которой есть HistoricalDataDownloader.class, com folder. Внутри HistoricalDataDownloader.java у меня есть import com.ib.client.* Кажется, ошибка связана с этим импортом. Когда я удаляю package historicalData, все работает нормально. Этот com/ib/client/* содержит сторонний исходный код, необходимый для запуска HistoricalDataDownloader класса.

limestreetlab 03.07.2024 03:48

Должен ли я переместить папку com из historicalData в родительскую папку ibapi, чтобы historicalData и com были братьями и сестрами? Все исходные файлы внутри com/ib/client объявлены package com.ib.client, значит import com.ib.client внутри HistoricalDataDownloader.java должно работать?

limestreetlab 03.07.2024 03:58

@limestreetlab Я предлагаю вам использовать IDE (IntelliJ, Eclipse, NetBeans, VS Code и т. д.) и, возможно, инструмент сборки (Maven, Gradle и т. д.). Это облегчит разработку нетривиальных Java-приложений. Тем не менее, если ваш код зависит от сторонней библиотеки, вам необходимо указать на нее при компиляции (и запуске) вашего приложения. См. варианты -cp / -classpath / --class-path или -p / --module-path. Хотя вы говорите «источник», возможно, вам действительно нужен -sourcepath/--source-path? Зависимости примечаний в Java практически всегда предварительно компилируются, так что это было бы нетипично.

Slaw 03.07.2024 03:58
Пожалуйста, никогда не публикуйте изображения текста. Они не доступны для поиска, мы не можем копировать и вставлять... Всегда копируйте и вставляйте текст и форматируйте его правильно. В настоящее время скриншот имеет лишь мимолетное сходство с расположением того, что вам все равно нужно скомпилировать. Вам было бы гораздо лучше сделать cd ~/dropbox/ibapi;find . -name \*.class -exec rm '{}' \;tree . и опубликовать результат в виде отформатированного кода.
g00se 03.07.2024 11:46

@limestreetlab dropbox/ibapi — это «корень» вашего кода, но dropbox/ibapi/historicaldata — это корень файлов com.ibm. Это не сработает. historicaldata — пакет высшего уровня. com — это пакет верхнего уровня. Оба каталога не являются родственными друг другу. В ошибках на вашем скриншоте следует сосредоточиться на части com.ibm not found. Не часть «невозможно загрузить класс» — она не может загрузить ваш класс, ПОТОМУ ЧТО com.ibm не найден. Если у вас с этим проблемы: прогуляйтесь, прежде чем бежать. Создайте очень простой исходный Java-файл на основе пакета с нулевым значением глубины и работайте с ним.

rzwitserloot 03.07.2024 14:32

Другие вопросы по теме