«Невозможно преобразовать ejbRef для ejb» при внедрении CDI (Weld) @Stateless EJB в компонент JSF2 @SessionScoped в Glassfish - PullRequest
6 голосов
/ 18 августа 2010

[ ОБНОВЛЕНИЕ : После обсуждения на форумах Glassfish / ML на http://forums.java.net/jive/thread.jspa?messageID=480532 была подана ошибка против Glassfish https://glassfish.dev.java.net/issues/show_bug.cgi?id=13040 для этой проблемы.]

Я пытаюсь внедрить локальное представление без интерфейса @Stateless EJB в компонент поддержки JSF2 @Named @ javax.enterprise.context.SessionScoped.EJB является одним из нескольких, которые расширяют абстрактный базовый базовый класс.Внедрение «@Inject TheEJBClass varName» завершается с ошибкой «Невозможно преобразовать ejbRef для ejb TheEJBClass в бизнес-объект класса типа my.package.name.TheAbstractBase». [править: На самом деле оказывается, что внедрение успешно выполнено, но разрешение метода во внедренном прокси-сервере для методов, унаследованных от суперклассов, не удается.] Если я использую "@EJB TheEJBClass varName", тогда varName остается нулевым, т.е.injected.

Подробности:

Я использую Glassfish 3.0.1 в Linux (Ubuntu 10.04 на случай, если это имеет значение), и у меня возникают реальные проблемы с обработкой инъекций EJB-моделей данных в мою сессию JSF2.модели с использованием CDI (Weld).И да, прежде чем вы спросите, у меня есть файл beans.xml, и CDI активируется для выполнения инъекции.

Если я внедряю его с аннотацией @EJB, например:

@EJB TheEJBClass memberName;

... EJB фактически не вводится, оставляя memberName пустым.

Если я внедряю его с аннотацией CDI @Inject:

@Inject TheEJBClass memberName;

... тогда CDI жалуется, когда я вызываюметод memberName, который реализован в суперклассе TheEJBClass и не переопределен в самом TheEJBClass, сообщая:

java.lang.IllegalStateException: Unable to convert ejbRef for ejb TheEJBClass to a business object of type class my.package.name.TheAbstractBase
    at
com.sun.ejb.containers.EjbContainerServicesImpl.getBusinessObject(EjbContainerServicesImpl.java:104)
at
org.glassfish.weld.ejb.SessionObjectReferenceImpl.getBusinessObject(SessionObjectReferenceImpl.java:60)
....

Я пытался преобразовать базовый класс в конкретный класс и де-генерировать его, но столкнулся ста же проблема, так что я не думаю, что я сталкиваюсь с ошибками Weld с базовыми базами (https://jira.jboss.org/browse/WELD-305, https://jira.jboss.org/browse/WELD-381, https://jira.jboss.org/browse/WELD-518).

Схема кода с полным пакетомуточнение аннотаций, добавленных для ясности:

// JSF2 managed backing bean.
//
// Called via #{someJSF2Model.value} in a JSF2 page
//
@javax.inject.Named
@javax.enterprise.context.SessionScoped
public class SomeJSF2Model implements Serializable {
   @javax.inject.Inject TheEJBClass member;

   public Integer getValue() {
       return member.getValue();
   }
   // blah blah
}

// One of several EJB classes that extend TheAbstractBase
@javax.ejb.Stateless
public class TheEJBClass extends TheAbstractBase {
  // blah blah
  // does **NOT** override "getValue()"
}

public abstract class TheAbstractBase {
    // blah blah
    public Integer getValue() {
        return 1;
    }
}

Обратите внимание, что инъекция работает , работает, если я переопределяю TheAbstractBase.getValue () в TheEJBClass или если я вызываю метод, определенный в TheEJBClass, ине суперкласс. Кажется,проблема связана с наследованием.

Очень похожий код, который использовал встроенные функции жизненного цикла и внедрения JSF2, но учитывая, что это новый проект, и CDI - это то, к чему стремятся в будущем, яЯ подумал, что лучше попытаться пойти на CDI.Вот что я начал с использования инъекции JSF2 / EJB, которая сработала:

// JSF2 managed backing bean. Using @ManagedBean and JSF2's @SessionScoped
// instead of CDI @Named and CDI @SessionScoped this time.
//
@javax.faces.bean.ManagedBean
@javax.faces.bean.SessionScoped
public class SomeJSF2Model implements Serializable {
   @javax.ejb.EJB TheEJBClass member;
   public Integer getValue() {
       return member.getValue();
   }
   // blah blah
}

// One of several EJB classes that extend TheAbstractBase
// Unchanged from CDI version
@javax.ejb.Stateless
public class TheEJBClass extends TheAbstractBase {
  // blah blah
  // does **NOT** override "getValue()"
}

// Unchanged from CDI version
public abstract class TheAbstractBase {
    // blah blah
    public Integer getValue() {
        return 1;
    }
}

В настоящее время я работаю над составлением отдельного тестового примера, но решил, что сейчас укажу вопрос вна случай, если я просто делаю что-то глупое или есть известное решение, которое не может найти мой Google-фу.Почему он работал с инъекцией JSF2 / EJB, но не работал с инъекцией CDI?

(С тех пор переиздан на форумах Glassfish как http://forums.java.net/jive/thread.jspa?threadID=152567)

1 Ответ

3 голосов
/ 29 ноября 2011

Как отмечено выше, это ошибка сварщика / стеклянной рыбы.

Исправлено: отказаться от Glassfish и перейти к JBoss AS 7, который на самом деле работает большую часть времени.

...