2

Description

I'm having a problem with creating an Arquillian test that rollbacks database operations at the end of execution. It throws a NullPointerException when trying to rollback the transaction because it can't find the org.jboss.arquillian.test.spi.TestResult instance from the org.jboss.arquillian.test.impl.context.TestContextImpl instance (testResultInstance.get() returns null, below).

I'm using arquillian-1.1.2-Final and arquillian-transaction-api-1.0.0-FINAL and testng-6.8.

I can see the transaction being created correctly at the beginning of the test method but I can't figure out why the org.jboss.arquillian.test.spi.TestResult is not set correctly and throws the exception.

Note: If I remove the @Transactional annotation from the test class, everything works fine. Also, in this test you'll see that there are no updates/inserts to the database but that's just for the sake of simplicity. If I add an update statement to it, the record is updated correctly but the change is persisted after the test ends (if I remove the @Transactional annotation from the test class) and I want to prevent that by rolling it back...

Info

Code where exception happens (first line of method below - from org.jboss.arquillian.transaction.impl.lifecycle.TransactionHandler):

/**
 * Returns whether the test requires to be rolled back. </p>
 * By default it will return true if the last executed test has failed.
 *
 * @return true if test requires rollback, false otherwise
 */
private boolean testRequiresRollbackDueToFailure()
{
   final Status actualStatus = testResultInstance.get().getStatus();
   return TestResult.Status.FAILED.equals(actualStatus);
}

Exception stacktrace:

java.lang.NullPointerException
    at org.jboss.arquillian.transaction.impl.lifecycle.TransactionHandler.testRequiresRollbackDueToFailure(TransactionHandler.java:159)
    at org.jboss.arquillian.transaction.impl.lifecycle.TransactionHandler.rollbackRequired(TransactionHandler.java:148)
    at org.jboss.arquillian.transaction.impl.lifecycle.TransactionHandler.endTransactionAfterTest(TransactionHandler.java:109)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.jboss.arquillian.core.impl.ObserverImpl.invoke(ObserverImpl.java:94)
    at org.jboss.arquillian.core.impl.EventContextImpl.invokeObservers(EventContextImpl.java:99)
    at org.jboss.arquillian.core.impl.EventContextImpl.proceed(EventContextImpl.java:81)
    at org.jboss.arquillian.testenricher.cdi.CreationalContextDestroyer.destory(CreationalContextDestroyer.java:44)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.jboss.arquillian.core.impl.ObserverImpl.invoke(ObserverImpl.java:94)
    at org.jboss.arquillian.core.impl.EventContextImpl.proceed(EventContextImpl.java:88)
    at org.jboss.arquillian.test.impl.TestContextHandler.createTestContext(TestContextHandler.java:102)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.jboss.arquillian.core.impl.ObserverImpl.invoke(ObserverImpl.java:94)
    at org.jboss.arquillian.core.impl.EventContextImpl.proceed(EventContextImpl.java:88)
    at org.jboss.arquillian.test.impl.TestContextHandler.createClassContext(TestContextHandler.java:84)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.jboss.arquillian.core.impl.ObserverImpl.invoke(ObserverImpl.java:94)
    at org.jboss.arquillian.core.impl.EventContextImpl.proceed(EventContextImpl.java:88)
    at org.jboss.arquillian.test.impl.TestContextHandler.createSuiteContext(TestContextHandler.java:65)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.jboss.arquillian.core.impl.ObserverImpl.invoke(ObserverImpl.java:94)
    at org.jboss.arquillian.core.impl.EventContextImpl.proceed(EventContextImpl.java:88)
    at org.jboss.arquillian.core.impl.ManagerImpl.fire(ManagerImpl.java:135)
    at org.jboss.arquillian.core.impl.ManagerImpl.fire(ManagerImpl.java:115)
    at org.jboss.arquillian.test.impl.EventTestRunnerAdaptor.after(EventTestRunnerAdaptor.java:103)
    at org.jboss.arquillian.testng.Arquillian.arquillianAfterTest(Arquillian.java:149)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
    at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:564)
    at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:213)
    at org.testng.internal.Invoker.invokeMethod(Invoker.java:786)
    at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
    at org.testng.TestRunner.privateRun(TestRunner.java:767)
    at org.testng.TestRunner.run(TestRunner.java:617)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291)
    at org.testng.SuiteRunner.run(SuiteRunner.java:240)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1224)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1149)
    at org.testng.TestNG.run(TestNG.java:1057)
    at org.jboss.arquillian.testng.container.TestNGTestRunner.execute(TestNGTestRunner.java:53)
    at org.jboss.arquillian.protocol.servlet.runner.ServletTestRunner.executeTest(ServletTestRunner.java:160)
    at org.jboss.arquillian.protocol.servlet.runner.ServletTestRunner.execute(ServletTestRunner.java:126)
    at org.jboss.arquillian.protocol.servlet.runner.ServletTestRunner.doGet(ServletTestRunner.java:90)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:734)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248)
    at org.jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:62)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161)
    at org.jboss.as.jpa.interceptor.WebNonTxEmCloserValve.invoke(WebNonTxEmCloserValve.java:50)
    at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:153)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930)
    at java.lang.Thread.run(Thread.java:619)

Test class:

package ie.one23.insurance.common.dao.config;

import ie.one23.insurance.motor.dao.lookup.LookupDao;
import ie.one23.insurance.motor.util.PackagingUtil;

import javax.inject.Inject;

import org.apache.poi.hssf.record.formula.functions.Lookup;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.container.test.api.OverProtocol;
import org.jboss.arquillian.testng.Arquillian;
import org.jboss.arquillian.transaction.api.annotation.TransactionMode;
import org.jboss.arquillian.transaction.api.annotation.Transactional;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.Assert;
import org.testng.annotations.Test;

@Transactional(TransactionMode.ROLLBACK)
public class TermsOfBusinessUrlDaoTest extends Arquillian {

    @Deployment
    @OverProtocol("Servlet 3.0")
    public static WebArchive createDeployment() {
        WebArchive war = PackagingUtil.getWebArchiveForEJB();
        return war;
    }

    @Inject
    LookupDao lookupDao;

    @Test(groups = { "daos", "integration", "arquillian" })
    public void testFindValidLinkByCode() {
        Lookup lookup = lookupDao.findValidLinkByCode("example");

        Assert.assertNotNull(lookup);
        Assert.assertEquals("example", lookup.getCode());
        Assert.assertEquals(true, lookup.getActive());
    }
}

arquillian.xml

<arquillian xmlns="http://jboss.org/schema/arquillian" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://jboss.org/schema/arquillian
        http://jboss.org/schema/arquillian/arquillian_1_0.xsd">

    <container qualifier="jboss-remote" default="false">
        <configuration>
            <property name="managementAddress">${mgmtAddr:127.0.0.1}</property>
            <property name="managementPort">${mgmtPort:9999}</property>
        </configuration>
    </container>

    <extension qualifier="transaction">
        <property name="manager">java:jboss/TransactionManager</property>
    </extension>

    <extension qualifier="persistence">
        <property name="defaultTransactionMode">ROLLBACK</property>
    </extension>

</arquillian>

The unit tests that are part of arquillian-extension-transaction show a bind of the TestResult before invoking the test method:

If I remove the bind instruction, I get the same exception... Is this bind correct?

See the following URL: https://github.com/arquillian/arquillian-extension-transaction/blob/master/impl-base/src/test/java/org/jboss/arquillian/transaction/impl/lifecycle/ClientSideTransactionHandlerTestCase.java

@Test
public void shouldRollbackTransaction() throws Exception
{

  getManager().getContext(ClassContext.class).activate(TestClass.class);

  Object instance = new TestClass();
  Method testMethod = instance.getClass().getMethod("rollbackTest");

  bind(TestScoped.class, TestResult.class, new TestResult(TestResult.Status.PASSED));

  getManager().fire(new org.jboss.arquillian.test.spi.event.suite.After(instance, testMethod));

  // checks if the transaction context has been disposed
  verify(mockTransactionContext).destroy();

  // verifies that the transaction has been rollback
  verify(mockTransactionProvider).rollbackTransaction(any(TransactionalTest.class));

  getManager().getContext(ClassContext.class).deactivate();

}

2 Answers2

5

A bit late, but I ran into the same problem and was able to resolve it.

The problem was a mismatch between the version of Arquillian core and Arquillian persistence.

For Arquillian Persistence version 1.0.0.Alpha7, when running with Arquillian Core 1.1.5.Final, this error was presenting itself.

If the Arquillian Core version is changed to 1.1.2.Final, the error goes away... :-D

drone.ah
  • 1,135
  • 14
  • 28
  • The bug seams to be fixed in the latest version 1.1.13.Final of Arquillian. I successfully got rid of the exception by using 1.1.13.Final of Arquillian Core and 1.0.0.Alpha7 of Arquillian Persistence Extension. Thanks for the Hint! – romixch Apr 05 '17 at 15:51
3

Arquillian Version 1.1.4.Final worked for me with arquillian-persistence-dbunit 1.0.0.Alpha7. Version 1.1.5.Final seems to be buggy with DB-Unit extension (see NPE above).

arquser
  • 31
  • 1