Reinis, If you use Arquillian + TomEE your tests will work much better (e.g. no thread issues). YOu can run TomEE embedded so it's not too much slower either. DeltaSpike is only a CDI library so it shouldn't impact your testing (so you're loading the libs up in to your WEB-INF/lib?)
John On Wed, Apr 10, 2013 at 3:45 PM, Reinis Vicups <[email protected]> wrote: > Thanks Mr. Ament for your input! > > Yes I think I will go with Arquillian, although Mr. Struberg is persisting > (no pun) me to go with DeltaSpike. > > The Prod. Env. is ofcourse TomEE+ > > I think that fully built application will even run in prod. env. but I > really want to test my app before deploying. One good reason in this > particular scenario is the "swallowed" exception especially if it could be > caused not because it's test setup but because am using @Asynchronous e.g. > > Thank you guys for the instant feedback, now I have to do some serious > Arquillian-re-factoring in my app o/ > Reinis > > > On 04/10/2013 09:32 PM, John D. Ament wrote: > >> I would hope those interested in Application Composer also look at >> Arquillian for their automated testing needs (BTW: is your production >> target ENV just OpenEJB + OWB?) >> >> I think part of your issue is your use of @asynchronous. >> >> >> On Wed, Apr 10, 2013 at 3:28 PM, Reinis Vicups <[email protected]> wrote: >> >> I guess, why is HeavyProcessingControllerProdu******cer session >>> scoped? >>> >>> There >>>> >>>> is no HTTP Session when this unit test runs, so no it won't be active at >>>> that time. >>>> >>>> Ok but why then the same session scoped bean is able to read from JPA >>> with >>> no issues two method calls before? >>> >>> As you may notice in stacktrace there's xyz.my.domain.User >>> (xyz.my.domain.User_$_****javassist_3.pcGetStateManager) This is the >>> >>> currently logged in user entity read from DB by JPA and passed up and >>> down >>> the stacktrace (injected or as param) in next to every method call. >>> >>> Reason why the HeavyProcessingControllerProdu****cer is session scoped >>> is >>> >>> that it produces stuff for currently logged in session user whether @New >>> or >>> existing. >>> >>> I understand your argument that theres no HTTP Session and it is obvious, >>> I just thought (am still hoping) that the ApplicationComposer does some >>> hard-core bootstrapping magic and weaves, javaasists or whatever dark >>> arts >>> are there required to allow me to junit-test all sorts of CDI/JSF/EJB >>> beans, no? :DDDD >>> >>> br >>> Reinis >>> >>> >>> >>> On 04/10/2013 09:14 PM, John D. Ament wrote: >>> >>> What you're seeing is correct (though I'm not a good one to ask why it's >>>> only at the trace level that you see this exception). >>>> >>>> I guess, why is HeavyProcessingControllerProdu******cer session scoped? >>>> >>>> There >>>> >>>> is no HTTP Session when this unit test runs, so no it won't be active at >>>> that time. >>>> >>>> >>>> On Wed, Apr 10, 2013 at 3:00 PM, Reinis Vicups <[email protected]> >>>> wrote: >>>> >>>> Hi guys, >>>> >>>>> got following scenario >>>>> >>>>> **>>>>>>>>>>>>>>>>>>>>>>>>>>>>****>>** >>>>> >>>>>> @org.junit.runner.RunWith(org.**** >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> **apache.openejb.junit.** >>>>> >>>>> ApplicationComposer) >>>>> public class IamIntegrationTest{ >>>>> >>>>> // ACHTUNG! >>>>> @javax.enterprise.inject.******Produces @javax.enterprise.inject.New >>>>> HeavyProcessingController heavyProcessingController; >>>>> >>>>> @org.apache.openejb.testing.******Module >>>>> public PersistenceUnit somePersistenceConfigHere() { >>>>> // boring code >>>>> } >>>>> >>>>> @org.apache.openejb.testing.******Configuration >>>>> >>>>> >>>>> public Properties settingUpSomeRessourceConfig() { >>>>> // boring code >>>>> } >>>>> >>>>> @Test >>>>> public void iAmHeavyIntegrationTestMethod(******) { >>>>> heavyProcessingController.******readALittleBitFromJPA(); >>>>> heavyProcessingController.******initiateSomeHeavyProcessing(); >>>>> } >>>>> } // end test class >>>>> >>>>> >>>>> @javax.enterprise.context.******SessionScoped >>>>> public class HeavyProcessingControllerProdu******cer { >>>>> >>>>> @Inject >>>>> JPAService jpaService; >>>>> >>>>> @Produces @RequestScoped >>>>> public List<SomeEntity> readALittleBitFromJPA() { >>>>> jpaService.getEntityList(); >>>>> } >>>>> >>>>> @javax.enterprise.inject.******Produces >>>>> @javax.enterprise.inject.New >>>>> public HeavyProcessingControllerprodu**** >>>>> **ceHeavyProcessingController(****) { >>>>> >>>>> >>>>> // ACHTUNG, invoking here JPA and it works! >>>>> readALittleBitFromJPA(); >>>>> >>>>> // ACHTUNG, doing this because of some complex initialization >>>>> logic required aforehand. >>>>> return org.apache.myfaces.extensions.******cdi.core.impl.util.** >>>>> CodiUtils.** >>>>> getContextualReferenceByClass(******HeavyProcessingController.** >>>>> ****class); >>>>> >>>>> >>>>> } >>>>> } // end Producer class >>>>> >>>>> >>>>> // ACHTUNG, this is stateful EJB Bean with no other explicit context >>>>> annotations! >>>>> @javax.ejb.Stateful >>>>> public class HeavyProcessingController implements Serializable { >>>>> >>>>> @Inject >>>>> AsyncHeavyProcessingWorker asyncWorker; >>>>> >>>>> public void initiateSomeHeavyProcessing() { >>>>> // ACHTUNG! @Asynchronous method is invoked here >>>>> asyncWorker.******asyncDoHeavyProcessingAndSaveY****** >>>>> >>>>> ourWorkIntoPersistence(); >>>>> >>>>> } >>>>> } >>>>> >>>>> >>>>> // ACHTUNG, this is stateful EJB Bean with no other explicit context >>>>> annotations! >>>>> @javax.ejb.Stateful >>>>> public class AsyncHeavyProcessingWorkerimpl******ements Serializable { >>>>> >>>>> @Inject >>>>> JPAService jpaService; >>>>> >>>>> @Asynchronous >>>>> >>>>> public void asyncDoHeavyProcessingAndSaveY**** >>>>> **ourWorkIntoPersistence(){ >>>>> // ACHTUNG! >>>>> jpaService.persist(******allThatHardWork); >>>>> >>>>> } >>>>> } >>>>> >>>>> @javax.ejb.Stateless >>>>> public class JPAService { >>>>> >>>>> @PersistenceContext >>>>> EntityManager em; >>>>> >>>>> // ACHTUNG, no explicit TransacactionAttribute, using defaults! >>>>> public void persist(SomeJPAEntity allThatHardWork) { >>>>> em.persist(allThatHardWork); >>>>> } <- ACHTUNG, exceptionsomewhere here! >>>>> } >>>>> >>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<******<<<<<<<<<<<<<<<<<<<<<<<<<<** >>>>> <<**<<** >>>>> >>>>> >>>>> <<<<<<<<<<<<<<<<<<<<<<<< >>>>> >>>>> Executing this code causes following exception: >>>>> >>>>> >>>>> 3389 default TRACE [@Asynchronous IntegrationTest - 1] >>>>> openjpa.Runtime >>>>> - org.apache.openjpa.******persistence.******EntityManagerFactoryImpl@ >>>>> **** >>>>> 51d62781 >>>>> created EntityManager org.apache.openjpa.**** >>>>> persistence.EntityManagerImpl@***** >>>>> *5ead44a4. >>>>> 123394 default TRACE [@Asynchronous IntegrationTest - 1] >>>>> openjpa.Runtime - An exception occurred while ending the transaction. >>>>> This >>>>> exception will be re-thrown. >>>>> javax.enterprise.context.******ContextNotActiveException: WebBeans >>>>> context >>>>> >>>>> >>>>> with scope type annotation @SessionScoped does not exist within current >>>>> thread >>>>> at org.apache.webbeans.container.******BeanManagerImpl.** >>>>> getContext(*** >>>>> * >>>>> BeanManagerImpl.java:351) >>>>> at org.apache.webbeans.intercept.******** >>>>> NormalScopedBeanInterceptorHan****** >>>>> dler.getContextualInstance(********NormalScopedBeanInterceptorHan** >>>>> **** >>>>> dler.java:143) >>>>> at org.apache.webbeans.intercept.******** >>>>> NormalScopedBeanInterceptorHan****** >>>>> dler.invoke(******NormalScopedBeanInterceptorHan******dler.java:114) >>>>> at org.apache.webbeans.intercept.******** >>>>> NormalScopedBeanInterceptorHan****** >>>>> dler.invoke(******NormalScopedBeanInterceptorHan******dler.java:108) >>>>> *_at xyz.my.domain.User_$$_******javassist_3.pcGetStateManager(****** >>>>> User_$$_javassist_3.java)_* >>>>> at org.apache.openjpa.kernel.******BrokerImpl.isDetached(** >>>>> BrokerImpl.java:4580) >>>>> at org.apache.openjpa.kernel.****** >>>>> SingleFieldManager.preFlushPC(****** >>>>> SingleFieldManager.java:775) >>>>> at org.apache.openjpa.kernel.****** >>>>> SingleFieldManager.preFlush(** >>>>> SingleFieldManager.java:621) >>>>> at org.apache.openjpa.kernel.****** >>>>> SingleFieldManager.preFlush(** >>>>> SingleFieldManager.java:589) >>>>> at org.apache.openjpa.kernel.****** >>>>> SingleFieldManager.preFlush(** >>>>> SingleFieldManager.java:505) >>>>> at org.apache.openjpa.kernel.******StateManagerImpl.preFlush(** >>>>> StateManagerImpl.java:2982) >>>>> at org.apache.openjpa.kernel.******PNewState.beforeFlush(** >>>>> PNewState.java:40) >>>>> at org.apache.openjpa.kernel.****** >>>>> StateManagerImpl.beforeFlush(****** >>>>> StateManagerImpl.java:1054) >>>>> at org.apache.openjpa.kernel.****** >>>>> BrokerImpl.flush(BrokerImpl.** >>>>> java:2112) >>>>> at org.apache.openjpa.kernel.******BrokerImpl.flushSafe(** >>>>> BrokerImpl.java:2072) >>>>> at org.apache.openjpa.kernel.****** >>>>> BrokerImpl.beforeCompletion(** >>>>> BrokerImpl.java:1990) >>>>> at org.apache.geronimo.******transaction.manager.**** >>>>> TransactionImpl.** >>>>> beforeCompletion(******TransactionImpl.java:527) >>>>> at org.apache.geronimo.******transaction.manager.**** >>>>> TransactionImpl.** >>>>> beforeCompletion(******TransactionImpl.java:512) >>>>> at org.apache.geronimo.******transaction.manager.** >>>>> TransactionImpl.beforePrepare(******TransactionImpl.java:413) >>>>> at org.apache.geronimo.******transaction.manager.**** >>>>> TransactionImpl.commit( >>>>> **TransactionImpl.java:262) >>>>> at org.apache.geronimo.******transaction.manager.** >>>>> TransactionManagerImpl.commit(******TransactionManagerImpl.** >>>>> java:****252) >>>>> at org.apache.openejb.core.******transaction.**** >>>>> JtaTransactionPolicy.** >>>>> completeTransaction(******JtaTransactionPolicy.java:328) >>>>> at org.apache.openejb.core.******transaction.TxRequired.commit(* >>>>> ***** >>>>> TxRequired.java:75) >>>>> at org.apache.openejb.core.******transaction.**** >>>>> EjbTransactionUtil.** >>>>> afterInvoke(******EjbTransactionUtil.java:76) >>>>> at org.apache.openejb.core.******stateful.StatefulContainer.** >>>>> afterInvoke(StatefulContainer.******java:843) >>>>> at org.apache.openejb.core.******stateful.StatefulContainer.** >>>>> businessMethod(******StatefulContainer.java:667) >>>>> at org.apache.openejb.core.******stateful.StatefulContainer.** >>>>> invoke(StatefulContainer.java:******364) >>>>> at org.apache.openejb.core.ivm.******EjbObjectProxyHandler.** >>>>> synchronizedBusinessMethod(******EjbObjectProxyHandler.java:******256) >>>>> at org.apache.openejb.core.ivm.******EjbObjectProxyHandler$1.** >>>>> call(*** >>>>> * >>>>> EjbObjectProxyHandler.java:******244) >>>>> at org.apache.openejb.async.******AsynchronousPool$** >>>>> AsynchronousCall.call(******AsynchronousPool.java:110) >>>>> at java.util.concurrent.******FutureTask$Sync.innerRun(** >>>>> FutureTask.java:334) >>>>> at java.util.concurrent.******FutureTask.run(FutureTask.****** >>>>> java:166) >>>>> at java.util.concurrent.******ThreadPoolExecutor.runWorker(*** >>>>> *** >>>>> ThreadPoolExecutor.java:1110) >>>>> at java.util.concurrent.******ThreadPoolExecutor$Worker.run(** >>>>> **** >>>>> ThreadPoolExecutor.java:603) >>>>> at java.lang.Thread.run(Thread.******java:722) >>>>> >>>>> >>>>> WARNING - Could NOT lazily initialize session context because NO active >>>>> request context >>>>> 123395 default TRACE [@Asynchronous IntegrationTest - 1] >>>>> openjpa.Runtime - org.apache.openjpa.****** >>>>> persistence.EntityManagerImpl@*** >>>>> >>>>> ***5ead44a4.close() >>>>> >>>>> invoked. >>>>> >>>>> I have following questions: >>>>> >>>>> 1.Why is that this exception is logged ONLY when setting openjpa.log to >>>>> Runtime=TRACE? In other cases it's "swallowed" (as in there's no >>>>> exception >>>>> thrown in jpaService.persist(******allThatHardWork);) >>>>> >>>>> >>>>> >>>>> 2. Why is this exception? I already access JPA from @SessionScoped bean >>>>> in >>>>> HeavyProcessingControllerProdu******cer.****** >>>>> produceHeavyProcessingControll >>>>> ****er() >>>>> >>>>> >>>>> when I readALittleBitFromJPA() and it reads from Database just fine. >>>>> >>>>> 3. If you care to comment on the design of those classes, I would love >>>>> to >>>>> here if it's ok or not >>>>> >>>>> Thanks guys for reading this lengthy e-mail and even more thanks if you >>>>> give your thought on this >>>>> Reinis. >>>>> >>>>> >>>>>
