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.