Чтобы понять, почему это исключение произошло, есть две вещи, чтобы понять:
- Как работает одна ссылка EJB другой EJB
- EJB загрузки классов
первой сделки Давайте с номером один, так что давайте имя сначала EJB (содержащий FirstEJBRemote
класс) EJB_A и второй EJB (кто пытается получить доступ к методу EJB_A) EJB_B. Не слишком глубоко вносятся аннотации и подобные материалы, единственный способ для EJB_B получить доступ к методам EJB_A - через интерфейс. Другими словами, EJB_A реализует некоторый интерфейс (в вашем случае это FirstEJBRemote
), который EJB_B объявляет и через инъекцию извлекает экземпляр EJB_A. Все идет нормально.
Далее мы должны понимать загрузчики классов EJB. Естественно, каждый внешний класс/библиотека, которую ваше приложение (в данном случае, EJB) использует во время компиляции, должно быть доступно также во время выполнения. В противном случае, ClassNotFoundException
будет отброшена, и это именно то, что произошло в вашем случае, поскольку EJB_B использует FirstEJBRemote
в компиляции:
private FirstEJBRemote ejb;
Чтобы обеспечить этот внешний класс/библиотеку в EJB во время выполнения, что нужно сделать что-то из следующего:
- Поместите класс/библиотеку в LIB каталоге сервера приложений
- обновления класс/библиотека вместе с EJB
- Поместите класс/библиотеку в пути к классам EAR, содержащий ваш EJB
Мы проигнорируем третий вариант, потому что вы сказали, что вас не интересуют EAR. Таким образом, вы можете поместить интерфейс FirstEJBRemote
(в виде файла .jar, конечно) в каталог lib из Glassfish, где он будет доступен как EJB_A, так и EJB_B (таким образом, вам не нужно упаковывать его ни с EJB_A), ни в вы также можете упаковать этот интерфейс вместе с EJB_B, заботясь о том, чтобы он находился в том же пакете, что и в EJB_A.
В своем комментарии вы задаетесь вопросом, почему эта «сложная» процедура необходима вообще. Ответ довольно прост - если EJB-загрузчики классов не были изолированы друг от друга, каждый класс, который был развернут с EJB_A, будет доступен для EJB_B. В этом конкретном случае это было бы желательным поведением, но представьте, что произойдет, когда EJB_A включает в себя версию1 некоторой библиотеки (например, библиотеку журналов), а EJB_B использует эту же библиотеку, но version2. Оба класса будут загружены, и вы столкнетесь с столкновением повсюду, ClassCastException
и т. Д. (Или, если вам повезет, EJB_B будет «только» вынужден использовать версию1, потому что этот класс уже будет загружен загрузчиком классов).
Наконец, выдержка из Oracle GlassFish 3.1 Guide:
обходя загрузчик классов Изоляции
Поскольку каждый загрузчик приложений или индивидуально развернут класса модуля вселенной изолирована, приложение или модуль не может загружать классы от другого приложения или модуля. Это предотвращает взаимодействие двух одинаково названных классов в разных приложениях или модулях от помех друг другу.
Пожалуйста вывесить фрагмент кода, где вы объявляете зависимость между EJBs. –
См. Редактирование. –