Вызов локального компонента EJB3 через удаленный компонент из внешней JVM - PullRequest
3 голосов
/ 16 ноября 2011

Не очень опытно с использованием EJB, и я столкнулся со следующей проблемой, с которой, я надеюсь, один из вас, ребята, может помочь.

Предположим, что следующая ситуация: набор @Local бинов был определен дляпредоставить доступ к базе данных.Эти компоненты очень просты и развернуты на сервере приложений A (Weblogic 10.3.3).Мы хотим предоставить доступ к этим локальным bean-компонентам через remote , и, поскольку у нас уже есть настройка модуля "services" для предоставления внешнего доступа к нашим услугам, наша идея заключалась в созданииновый сервис @Remote, который использует локальные bean-компоненты, описанные выше (внедренный через @EJB).Эти служебные бины также развертываются на сервере приложений A. Например:

@Local
public interface DatabaseBeanLocal { doStuff(); }

@Stateless(name = "ejb/DatabaseBean", mappedName = "DatabaseBean")
public class DatabaseBean implements DatabaseBeanLocal { doStuff() { ... } ; }

@Remote
public interface ServiceBean { doSomeOtherStuff(); }

@Stateless
public class ServiceBeanImpl implements ServiceBean
{
    @EJB(name = "ejb/DatabaseBean", mappedName = "DatabaseBean")
    private DatabaseBeanLocal myDatabaseBean;

    ... methods etc. ...

}

Клиент, который фактически будет использовать эти удаленные бины, фактически выполняется на другом сервере приложений; сервер приложений B (также Weblogic 10.3.3).Когда мы ищем bean-компонент ServiceBean от нашего клиента, это прекрасно работает.Однако когда мы вызываем для него метод, которому требуется доступ к DatabaseBean, вызов завершается неудачно.Сервер Weblogic сообщает, что не может найти компонент для интерфейса DatabaseBean.

Мои вопросы: возможна ли такая настройка?Другими словами: будет ли Weblogic (или другой контейнер) внедрять локальный компонент в удаленный компонент, чтобы клиент получил экземпляр удаленного компонента, который способен вызывать действия с локальным компонентом (полагаю, нет, но я спрашиваюв любом случае, чтобы быть уверенным)?

Если нет, я думаю, у нас не будет другого выбора, кроме как пропустить уровень обслуживания и предоставить прямой доступ к приведенному выше примеру DatabaseBean через @Remote.

Обновление 1

После выполнения некоторых тестов просто определите DatabaseBean выше как @Remote вместо @Local, чтобы «исправить» эту проблему.Конечно, это не совсем исправление, так как это будет вызывать DatabaseBean удаленно, что смешно, потому что он находится в том же модуле, что и служба.Я начинаю подозревать, что обертывание локального EJB с удаленным EJB просто невозможно.

Обновление 2

То, что мы нашли до сих пор:

  • До сих пор мы не смогли вручную внедрить локальный EJB-компонент, поскольку на самом деле мы не можем найти его во время выполнения.
  • Очевидно, что Weblogic не включает локальные EJB-объекты в дерево JNDI.
  • ВызовServiceBean извне AS, на котором она развернута, все еще не работает, потому что зависимость от локального EJB никогда не разрешается или не разрешается на стороне клиента, что означает, что она не найдена.

Ответы [ 2 ]

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

Локальный означает локальный для EAR, а не для AS.

Ваш локальный и удаленный компоненты должны быть в одном EAR (не только в одной AS). Они?

- редактировать -

Хм .. Если они находятся в одном EAR, то это должно работать. То есть ответ на ваш вопрос «возможна ли такая настройка?» - это Да.

К сожалению, сейчас мы говорим о простой и простой отладке. Первое, что я хотел бы сделать, это попробовать и проверить, действительно ли локальный компонент (DatabaseBean я думаю) зарегистрирован и работает, используя WebPhere UTC эквивалент в WebLogic (я никогда не работал в WebLogic). Я могу перечислить 100 других вещей, которые вы можете проверить на наличие дополнительных журналов / следов / симптомов, но хорошо, это способ отладки.

1 голос
/ 18 ноября 2011

удалось решить эту проблему. следующая конфигурация работает для Weblogic 10.3.3 и позволяет удаленному EJB использовать локальный EJB, где удаленный EJB может вызываться из любого места.

В конечном итоге & mdash; после много испытаний & mdash; уловка, очевидно, заключалась в указании значения beanName для аннотации @EJB, используемой для пометки локального компонента как зависимости от удаленного компонента. Doh!

Развертывание

  • @Local EJB развернут на AS-A в EAR-1 (в своем собственном модуле / JAR)
  • @Remote EJB развернут на AS-A в EAR-1 (в своем собственном модуле / JAR)
  • Код клиента, который вызывает удаленную службу, развернут на AS-B в своем собственном архиве EAR

Аннотации

local EJB - это очень простой и понятный EJB-компонент со следующим интерфейсом и реализацией:

@Local
public interface LocalBeanLocal {
    // Implementation omitted
}

@Stateless(name = "LocalBean")
public class LocalBean implements LocalBeanLocal {
    // Implementation omitted
}

remote EJB снова является относительно простым EJB-компонентом, за исключением того, что он зависит от LocalBean. Эта зависимость выражается через аннотацию @EJB; но может показаться, что атрибут beanName необходим для правильного разрешения этой зависимости в Weblogic. Без атрибута beanName вызов удаленного EJB не будет работать для нас (в том смысле, что всегда будет какая-то ошибка, когда задействован локальный компонент)!

@Remote
public interface RemoteBeanRemote {
    // Implementation omitted
}

@Stateless(name = "RemoteBean")
public class RemoteBean implements RemoteBeanRemote {

    @EJB(beanName = "LocalBean")
    private LocalBeanLocal localBean;

    // Implementation omitted
}

Здесь, по-видимому, важно то, что атрибут beanName в объявлении зависимости удаленного сервиса (@EJB(beanName = "LocalBean")) должен иметь то же значение , что и имя бина, определенное в локальной реализации бина (* 1047) *).

* * Поиск тысяча сорок-девять

Получение ссылки на ваш удаленный EJB выполняется традиционным способом, кажется, нет особых требований. В нашем случае мы ищем удаленный сервис через JNDI.

...