EJB3Unit требует бизнес-интерфейса для @LocalBean - PullRequest
2 голосов
/ 26 февраля 2012

Я пытаюсь справиться с EJB3Unit , чтобы провести модульное тестирование EJB 3.1 без сохранения состояния, но EJB3Unit жалуется, потому что мой EJB не имеет "бизнес-интерфейса".Но я думал, что все эти вещи «бизнес-интерфейса» являются пережитком EJB 2, поэтому мне это не нужно.Это потому, что я неправильно использую EJB3Unit?Что мне нужно сделать, чтобы EJB3Unit работал для моего модульного теста?

Мой EJB по сути такой:

package uk.co.nildram.badamson.aoc4;

@Stateless
@LocalBean
public class AocService {

   @PersistenceContext(unitName = "aoc4")
   private EntityManager entityManager;

   // Other code
}

Мой класс модульного теста по сути такой:

package uk.co.nildram.badamson.aoc4;

public final class AocServiceTest extends BaseSessionBeanFixture<AocService> {

   private static final Class<?>[] USED_ENTITY_BEANS = {};

   public AocServiceTest() {
      super(AocService.class, USED_ENTITY_BEANS);
   }

   @Test
   public void testCreateSessionBean() {
      final AocService bean = getBeanToTest();
      checkInvariants(bean);
   }

   public static void checkInvariants(final AocService service) {
      // assertions
   }

   // Other code

}

Модульные тесты не пройдены из-за следующего исключения:

 java.lang.IllegalStateException: No business interface found on class 'uk/co/nildram/badamson/aoc4/AocService'.
at  com.bm.ejb3metadata.annotations.helper.bean.session.SessionBusinessInterfaceFinder.resolve(SessionBusinessInterfaceFinder.java:86)
at com.bm.ejb3metadata.annotations.helper.bean.SessionBeanHelper.resolve(SessionBeanHelper.java:69)
at com.bm.ejb3metadata.annotations.helper.ResolverHelper.resolve(ResolverHelper.java:91)
at com.bm.ejb3metadata.MetadataAnalyzer.analyze(MetadataAnalyzer.java:82)
at com.bm.ejb3metadata.MetadataAnalyzer.analyzeClasses(MetadataAnalyzer.java:49)
at com.bm.ejb3metadata.MetadataAnalyzer.initialize(MetadataAnalyzer.java:36)
at com.bm.ejb3metadata.annotations.metadata.MetaDataCache.getMetaData(MetaDataCache.java:129)
at com.bm.ejb3metadata.annotations.metadata.MetaDataCache.getDynamicModuleCreator(MetaDataCache.java:105)
at com.bm.creators.SessionBeanFactory.getInjector(SessionBeanFactory.java:78)
at com.bm.creators.SessionBeanFactory.createSessionBean(SessionBeanFactory.java:60)
at com.bm.testsuite.BaseSessionBeanFixture.setUp(BaseSessionBeanFixture.java:92)
at junit.framework.TestCase.runBare(TestCase.java:132)
at junit.framework.TestResult$1.protect(TestResult.java:110)
at junit.framework.TestResult.runProtected(TestResult.java:128)
at junit.framework.TestResult.run(TestResult.java:113)
at junit.framework.TestCase.run(TestCase.java:124)
at junit.framework.TestSuite.runTest(TestSuite.java:243)
at junit.framework.TestSuite.run(TestSuite.java:238)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

Код, генерирующий исключение, выглядит как http://ejb3unit.sourceforge.net/xref/com/bm/ejb3metadata/annotations/helper/bean/session/SessionBusinessInterfaceFinder.html. Это действительно кажется требовательныминтерфейс "javax / ejb".Но у меня есть @LocalBean, поэтому мой класс не должен требовать никаких интерфейсов.

1 Ответ

2 голосов
/ 26 февраля 2012

Удаленный и локальный бизнес-интерфейсы являются частью EJB 3.x (представлен в EJB 3.0), а не реликтом из EJB 2.x. Реликвией, на которую вы ссылаетесь, может быть, являются удаленные и локальные домашние интерфейсы EJB 2.x - те, которые вынуждают расширять javax.ejb.EJBHome / EJBLocalHome и вынуждают предоставлять методы создания.

Вы используете концепцию представления без интерфейса (без отдельных бизнес-интерфейсов), который является частью EJB 3.1, а EJB3Unit поддерживает только EJB 3.0, и поэтому он не работает. Вам нужен интерфейс, который аннотирован с помощью @Local или @Remote и сделайте AocService для его реализации, а затем используйте AocService через его интерфейс.

Спецификация EJB 3.1 использует следующую терминологию:

Примечание по терминологии: в данной спецификации используется термин «удаленный бизнес». интерфейс для ссылки на бизнес-интерфейс сеанса EJB 3.x бин, который поддерживает удаленный доступ. Термин удаленный интерфейс используется для обратитесь к интерфейсу удаленного компонента представления клиента EJB 2.1. Термин локальный бизнес-интерфейс относится к местному бизнесу интерфейс сессионного компонента EJB 3.x, который поддерживает локальный доступ. Термин локальный интерфейс используется для обозначения локального интерфейса компонента клиентского представления EJB 2.1.

Пример с EJB 3.x удаленным бизнес-интерфейсом, локальным бизнес-интерфейсом и представление без интерфейса:

@javax.ejb.Local
public interface LocalBusinessInterface {
}

@javax.ejb.Remote
public interface RemoteBusinessInterface {
}

//@LocalBean is annotation that was introduced in EJB 3.1
//according Javadoc it "Designates that a session bean exposes a 
//no-interface view."
//When bean does not implement other interfaces, using @LocalBean
//is redundant, because beans without any interfaces expose no-interface view
//by default.
@LocalBean
@Stateless
public class BeanImplementation 
    implements LocalBusinessInterface, RemoteBusinessInterface {
}
...