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.
Убедитесь, что у вас есть боб. Это может показаться чем-то очевидным, но я потратил много времени, пытаясь понять, почему я не смог получить экземпляр моего сервиса в тестах. Причина в том, что я пропустил аннотацию без гражданства.
Добавьте модуль при создании контейнера, как указал @Dzhu. Для maven классов будут целевые / классов, для maven тестов будут целевые / test-классы.
Что-то не так, если вы нашли сообщение, как
SEVERE: EJB6005:No EJB modules found
в консоли. Он говорит вам, что нет аннотированных классов без состоянияВзгляните на встроенную консоль 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