kyberorg
@kyberorg

Взаимодействие между двумя EJB-модулями внутри одного приложения?

Привет, Хабралюди!


При попытке получить EJB из другого модуля возникает NullPointerException.

Приведу пример, чтобы было понятнее.


Общая структура приложения такая:


EAR

|

— core.jar (EJB-модуль с основными бинами) — ядро приложения

|

— app.jar (другой EJB-модуль с бинами) — бизнес-логика

|

— web.war (сервлеты)


В code.jar объявлен такой EJB:

@LocalBean
@Singleton
@Startup
public class AppInfo(){
   private int counter;
   
   public void incCounter(){
     counter++;
  }
  public int getCounterValue(){
    return counter;
  }

}



В модуле app.jar есть Stateless бин который пытается читать значение counter'a.

@Stateless
public class SomeBean{
   @EJB private AppInfo appinfo;

    public void run(){
       int counter = appInfo.getCounterValue(); // здесь метод падает с NPE 
       System.out.println("Counter value is: "+counter);
   }   
}



В модуле web.war есть сервлет который, который при каждом запросе увеличивает счетчик:
public class MyServlet extends HttpServlet{
        @EJB private AppInfo appInfo;
        protected void doPost(params){
              appInfo.incCounter();
              ...
              other code
       }
  }



При дебаге видно:

В сервлете все работает: при входе в doPost() значение appInfo — это Proxy объект для AppInfo EJB.

В SomeBean возникает NPE: при входе в run() значение appInfo — null.


Как правильно инжектировать EJB из модуля Core в EJB из модуля App?


P.S. Деплоится EAR'ник на JBoss 6.1 EAP

P.S.S. Через Remote интерфейс пробовал: не работает (appInfo — null+NPE в методе)
  • Вопрос задан
  • 3922 просмотра
Пригласить эксперта
Ответы на вопрос 4
KingOfNothing
@KingOfNothing
Необходимо ж, наверное, не только объявить @EJB private AppInfo appInfo; Но и еще создать бин?
Типа appInfo = new AppInfo();

Или вы не хотите вручную создавать?
Ответ написан
Evgin
@Evgin
Вариант предложенный выше с созданием инстанса AppInfo через new — неверный по идеологии ee. Инжекция в сервлет должна работать. Проверьте документацию по конкретной версии контейнера. Есть подозрения что нужно инжектить в сервлет не класс AppInfo, а local-интерфейс.
Ответ написан
@zarc69
В моем проекте работает инжекция через @Local интерфейс.
Ответ написан
Комментировать
@bobzer
Java EE Developer
Вы не показали, как создается SomeBean. Я это к тому, что контейнер делает инъекцию в бины, которые сам создает. Если вы SomeBean создали через new, то никаких инъекций в него не будет.

Также можно покопать в сторону загрузки классов, которая в свежем JBoss-е существенно переработана, в сравнении с предыдущими версиями. Попробуйте, например в jboss-deployment-structure.xml указать <ear-subdeployments-isolated>false</ear-subdeployments-isolated>. В конце-концов, объедините core.jar и app.jar в один jar (тупо средствами WinRar-а, если долго переделывать скрипты сборки) и посмотрите, будет ли инъекция. Если будет — то 99% что надо ковырять загрузку классов. Если нет, то это скорее всего ни при чем, и надо думать дальше.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы