Java EE 6 - встроенные тесты контейнера EJB

Этот вопрос касается Java EE 6, использующего Glassfish v3 Embedded-All.

У меня есть модульный тест, который использует EJBContainer для проверки моего EJB без сохранения состояния. Проблема в том, что у меня проблемы с поиском EJB (удаленного) с использованием JNDI:

setup() {

  ctx = EJBContainer.createEJBContainer().getContext();

}

...

test() {

BookService bookService = (BookService)ctx.lookup("java:global/BookServiceEJB!com.something.service.BookService");

...

}

@Stateless
public class BookServiceEJB implements BookService {
...
}

@Remote
public interface BookService {
...
}

дает исключение:

javax.naming.NamingException: Lookup failed for 'java:global/BookServiceEJB!com.something.service.BookService' in SerialContext  [Root exception is javax.naming.NameNotFoundException: BookServiceEJB!com.something.service.BookService not found]

...

caused by: javax.naming.NameNotFoundException: BookServiceEJB!com.something.service.BookService not found

Я пробовал несколько путей ресурсов JNDI:

например

java:global/BookServiceEJB

java:global/BookService

четное:

java:global/BookShelf-1.0-SNAPSHOT/BookServiceEJB

так далее...

ничего не работает

У меня нет настроенных файлов развертывания xml, только persistence.xml в META-INF.

Тест использует Maven Верный:

mvn clean test

Любая помощь очень ценится!

Примечание. Полное развертывание на сервере Glassfish работает (с использованием appclient и @EJB инъекции)

3 ответа

Решение

После долгих поисков нашел решение, которое работает на меня...

Вам нужно настроить EJBContainer с помощью свойства: EJBContainer.MODULES и местоположения, в котором находятся классы модуля (если используется maven, 'target/classes').

например

...
props = new Properties();
props.put(EJBContainer.MODULES, new File("target/classes"));
ec = EJBContainer.createEJBContainer(props);
...

Если ваш EJB-компонент использует JPA, существует еще одна проблема, заключающаяся в том, что вы не сможете определить источник данных во встроенном контейнере, поэтому необходимо использовать ds по умолчанию: "jdbc/__default".

так, например, мой persistence.xml выглядит так:

<?xml version="1.0" encoding="UTF-8"?>

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
    version="1.0">

    <persistence-unit name="bookshelf" transaction-type="JTA">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <class>com.blah.domain.Book</class>
        <jta-data-source>jdbc/__default</jta-data-source>
        <properties>
            <property name="eclipselink.logging.level" value="INFO"/>
        </properties>
    </persistence-unit>

</persistence> 

Я не выяснил, как настроить встроенный тест контейнера для использования одного DS (jdbc/__default) и моего приложения для использования другого (например, jdbc/booksDS)

см.: http://www.mentby.com/glassfish/embedded-testing-woes.html

см.: http://forums.java.net/jive/thread.jspa?messageID=395759

Честно говоря, я не знаю, почему люди беспокоятся о Java EE, когда такие решения, как spring, намного проще...

Это очень расстраивало и тратило много времени... надеюсь, это поможет.

Есть несколько элементов, которые необходимо проверить, чтобы убедиться, что вы можете загрузить bean-компонент через context.lookup, избегая исключения NamingException.

  1. Убедитесь, что у вас есть боб. Это может показаться чем-то очевидным, но я потратил много времени, пытаясь понять, почему я не смог получить экземпляр моего сервиса в тестах. Причина в том, что я пропустил аннотацию без гражданства.

  2. Добавьте модуль при создании контейнера, как указал @Dzhu. Для maven классов будут целевые / классов, для maven тестов будут целевые / test-классы.

  3. Что-то не так, если вы нашли сообщение, как SEVERE: EJB6005:No EJB modules found в консоли. Он говорит вам, что нет аннотированных классов без состояния

  4. Взгляните на встроенную консоль Glassfish! Там вы увидите имена для поиска ваших бобов. Обратите внимание на сообщения в формате INFO: EJB5181:Portable JNDI names for EJB YourBean: [java:global/classes/YourBean!bean.package.YourBean, java:global/classes/YourBean], Это означает, что вы можете найти ваш бин, позвонив context.lookup("java:global/classes/YourBean!bean.package.YourBean") или по более короткому имени context.lookup("java:global/classes/YourBean") что может быть полезно, если нет столкновений имен.

Надеюсь, это кому-нибудь поможет. Было бы очень полезно иметь эти советы.

Я написал небольшое руководство по использованию встроенного контейнера glassfish 3.1, в котором также рассматривается вопрос о необходимости использования другого файла persistence.xml для тестов. Также исправление сбоев контейнера с помощью удаленных интерфейсов и веб-сервисов. Вы можете проверить это на http://pschyska.blogspot.com/2011/06/unit-testing-ejb-31-with-netbeans-maven.html

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