arquillian-extension-jacoco
arquillian-extension-jacoco copied to clipboard
@Startup EJB annoation problem
Hi, I have som ejb beans which are marked with @Startup annotation. When I try to run Arquillian tests in managed container and I try to measure code coverage with arquillian jacoco extension I get following exception.
09:27:08,837 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-4) MSC00001: Failed to start service jboss.deployment.subunit."ear.ear"."logic-0.0.1-SNAPSHOT.jar".component.SomeOtherBean.START: org.jboss.msc.service.StartException in service jboss.deployment.subunit."ear.ear"."logic-0.0.1-SNAPSHOT.jar".component.SomeOtherBean.START: Failed to start service
at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1767) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) [rt.jar:1.7.0_10]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) [rt.jar:1.7.0_10]
at java.lang.Thread.run(Thread.java:722) [rt.jar:1.7.0_10]
Caused by: java.lang.IllegalStateException: JBAS011048: Failed to construct component instance
at org.jboss.as.ee.component.BasicComponent.constructComponentInstance(BasicComponent.java:163)
at org.jboss.as.ee.component.BasicComponent.createInstance(BasicComponent.java:85)
at org.jboss.as.ejb3.component.singleton.SingletonComponent.getComponentInstance(SingletonComponent.java:116)
at org.jboss.as.ejb3.component.singleton.SingletonComponent.start(SingletonComponent.java:130)
at org.jboss.as.ee.component.ComponentStartService.start(ComponentStartService.java:44)
at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
... 3 more
Caused by: javax.ejb.EJBException: java.lang.NullPointerException
at org.jboss.as.ejb3.tx.CMTTxInterceptor.handleExceptionInOurTx(CMTTxInterceptor.java:166)
at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInOurTx(CMTTxInterceptor.java:230)
at org.jboss.as.ejb3.tx.CMTTxInterceptor.requiresNew(CMTTxInterceptor.java:333)
at org.jboss.as.ejb3.tx.SingletonLifecycleCMTTxInterceptor.processInvocation(SingletonLifecycleCMTTxInterceptor.java:56)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288)
at org.jboss.as.ejb3.component.interceptors.CurrentInvocationContextInterceptor.processInvocation(CurrentInvocationContextInterceptor.java:41)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288)
at org.jboss.as.ee.component.TCCLInterceptor.processInvocation(TCCLInterceptor.java:45)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288)
at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61)
at org.jboss.as.ee.component.BasicComponent.constructComponentInstance(BasicComponent.java:161)
... 9 more
Caused by: java.lang.NullPointerException
at org.jboss.arquillian.extension.jacoco.container.ArquillianRuntime.swapExecutionData(ArquillianRuntime.java:78)
at pl.borysfan.logic.SomeOtherBean.$jacocoInit(SomeOtherBean.java)
at pl.borysfan.logic.SomeOtherBean.(SomeOtherBean.java)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) [rt.jar:1.7.0_10]
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) [rt.jar:1.7.0_10]
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) [rt.jar:1.7.0_10]
at java.lang.reflect.Constructor.newInstance(Constructor.java:525) [rt.jar:1.7.0_10]
at java.lang.Class.newInstance0(Class.java:372) [rt.jar:1.7.0_10]
at java.lang.Class.newInstance(Class.java:325) [rt.jar:1.7.0_10]
at org.jboss.as.weld.injection.WeldEEInjection.produce(WeldEEInjection.java:100)
at org.jboss.as.weld.injection.WeldManagedReferenceFactory.getReference(WeldManagedReferenceFactory.java:77)
at org.jboss.as.ee.component.ManagedReferenceInterceptorFactory$ManagedReferenceInterceptor.processInvocation(ManagedReferenceInterceptorFactory.java:90)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288)
at org.jboss.invocation.WeavedInterceptor.processInvocation(WeavedInterceptor.java:53)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288)
at org.jboss.as.ee.component.NamespaceContextInterceptor.processInvocation(NamespaceContextInterceptor.java:50)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288)
at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInOurTx(CMTTxInterceptor.java:228)
... 18 more
I have some example project with this case. If you want to see it I can send you zip project. Cheers, Dominik
I also have the exact same problem. Any progress on this? I dont think it is related to the @Startup annotation though.
Do you mix EJB and CDI annotations? When I was removing one of them it had started working.
It's probably starting the EJB before the @Test request from Arquillian comes to start the arquillian integration. Need to change how we store and retrieve the data.
In my case the class is a @javax.ejb.Singleton. Unfortunately I cannot remove the annotation. Are there any possible workarounds? @aslakknutsen : Any pointers on where I can fix it in the arquillian-extension-jacoco code? Or is it only to do with arquillian and not the jacoco extension?
I think a quick fix might be to simply move the code that creates the RuntimeData: https://github.com/arquillian/arquillian-extension-jacoco/blob/master/src/main/java/org/jboss/arquillian/extension/jacoco/container/StartCoverageData.java#L44
to the private constructor here: https://github.com/arquillian/arquillian-extension-jacoco/blob/master/src/main/java/org/jboss/arquillian/extension/jacoco/container/ArquillianRuntime.java#L50
In jacoco 0.6.3 problem still exists..
Quick fix helped.. but im not sure if its right way... Mayby if should check if runtime is set and only then do synchronized block..
How did it help?
Mayby if should check if runtime is set and only then do synchronized block..
Wouldn't you then just silently ignore some coverage data until someone sets the runtime.. ?
Yesterday i upgraded plugin on our company projects from Alpha2 (jacoco 0.5.3) to latest with my patch for jacoco 0.6.3 and initialization at ArquillianRuntime constructor.
Looks like its working (i see that on remote jboss classes are instrumented, and looks like data is gathered.. i got jacoco.exec and so on) but on our sonar instance there is no coverage from remote executions. Im still investigating what can be a problem.
Wouldn't you then just silently ignore some coverage data until someone sets the runtime.. ?
It had to be "dirty" fix.. better to have some data than none.. But yes.. its not best idea..
I tried to debug how to make that fix better and it looks like sometimes coverage data is missing.
I dont know why but method _public void swapExecutionData(Object[] args)_ is sometimes not called during test. (after test neither) It happens for same tests always, and Im not able to find pattern why its always for that tests.
This is a In Container test, and not one that is executed on the client side?
Yes.. container test...
Could you post the test class?
I have coverage for only first test metod in that file (in my case its diga3, first by name) If i change names then other first will get coverage..
But in my other more complicated system only first method from class is missed.. so im bit dumb :) Tests there are not that complicated..
I have tried on different scenarios, bot nothing helps... like
- disabling listeners for JUnit
- disabling one deployment thru arquillian-suilte-deployment
- reverting to pre fix version (for that version is not neede)
- doing a lot of dumb changes in arquilian-extension-jacoco
package testit;
public class DigIt {
public void dig1() {
System.out.println("dig1");
}
public void dig2() {
System.out.println("dig2");
}
public void dig3() {
System.out.println("dig3");
}
public void dig4() {
System.out.println("dig4");
}
}
And test
@RunWith(Arquillian.class)
public class DigItTest {
@Deployment
public static Archive<?> globalDeployment() {
return ShrinkWrap.create(WebArchive.class, "normal.war")
.addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml")
.addPackage(DigIt.class.getPackage());
}
DigIt dig = new DigIt();
@Test
public void testDig2() {
dig.dig2();
}
@Test
public void testDig1() {
dig.dig1();
}
@Test
public void testDiga3() {
dig.dig3();
}
@Test
public void testDig4() {
dig.dig4();
}
}
After some extra investigation i found some clues.
- Patch made by Robert Panzer https://github.com/arquillian/arquillian-extension-jacoco/commit/b05d871daf18864b7fdec643d4994ec03cf920e6 (because of rewriting RuntimeData from StartCoverageData) is only covenring first method in file.
- After my "dirty" patch its working almost ok.
What I mean almost is that when Im testing bigger project (and we are doing it by uisng arquillian-suite-extension witch one deployment) then some data is missing (for example in class DigIt only class entrace is shown as covered) public class DigIt {
Its really hard to tell why, mayby i will have some time for further investigation, but mayby you have any ideas?