Demoiselle Junit - Nullpointerexception

Asked

Viewed 531 times

9

When running a unit test with br.gov.frameworkdemoiselle.junit.DemoiselleRunner, the following error is happening at the end of the test run:

java.lang.NullPointerException
    at br.gov.frameworkdemoiselle.internal.bootstrap.SeBootstrap.removeContexts(SeBootstrap.java:70)
    at br.gov.frameworkdemoiselle.internal.bootstrap.SeBootstrap$Proxy$_$$_WeldClientProxy.removeContexts(SeBootstrap$Proxy$_$$_WeldClientProxy.java)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.jboss.weld.util.reflection.SecureReflections$13.work(SecureReflections.java:267)
    at org.jboss.weld.util.reflection.SecureReflectionAccess.run(SecureReflectionAccess.java:52)
    at org.jboss.weld.util.reflection.SecureReflectionAccess.runAsInvocation(SecureReflectionAccess.java:137)
    at org.jboss.weld.util.reflection.SecureReflections.invoke(SecureReflections.java:263)
    at org.jboss.weld.introspector.jlr.WeldMethodImpl.invokeOnInstance(WeldMethodImpl.java:164)
    at org.jboss.weld.introspector.ForwardingWeldMethod.invokeOnInstance(ForwardingWeldMethod.java:51)
    at org.jboss.weld.injection.MethodInjectionPoint.invokeOnInstanceWithSpecialValue(MethodInjectionPoint.java:154)
    at org.jboss.weld.event.ObserverMethodImpl.sendEvent(ObserverMethodImpl.java:245)
    at org.jboss.weld.event.ObserverMethodImpl.sendEvent(ObserverMethodImpl.java:233)
    at org.jboss.weld.event.ObserverMethodImpl.notify(ObserverMethodImpl.java:213)
    at org.jboss.weld.event.ObserverNotifier.notifyObserver(ObserverNotifier.java:117)
    at org.jboss.weld.event.ObserverNotifier.notifyObservers(ObserverNotifier.java:85)
    at org.jboss.weld.event.ObserverNotifier.fireEvent(ObserverNotifier.java:75)
    at org.jboss.weld.event.ObserverNotifier.fireEvent(ObserverNotifier.java:70)
    at org.jboss.weld.manager.BeanManagerImpl.fireEvent(BeanManagerImpl.java:580)
    at br.gov.frameworkdemoiselle.junit.DemoiselleRunner.shutdown(DemoiselleRunner.java:88)
    at br.gov.frameworkdemoiselle.junit.DemoiselleRunner.runChild(DemoiselleRunner.java:63)
    at br.gov.frameworkdemoiselle.junit.DemoiselleRunner.runChild(DemoiselleRunner.java:49)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at br.gov.frameworkdemoiselle.junit.DemoiselleRunner.run(DemoiselleRunner.java:73)
    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:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

It is an application module that runs as a service. That is, it does not run on any application server. The purpose of running the tests with the DemoiselleRunner is to enable the ICD.

The dependencies of the department I have are as follows:

        <dependency>
            <groupId>br.gov.frameworkdemoiselle.component</groupId>
            <artifactId>demoiselle-junit</artifactId>
            <version>2.3.1</version>
        </dependency>

        <dependency>
            <groupId>br.gov.frameworkdemoiselle</groupId>
            <artifactId>demoiselle-core</artifactId>
            <version>2.4.1</version>
        </dependency>

        <dependency>
            <groupId>br.gov.frameworkdemoiselle</groupId>
            <artifactId>demoiselle-jpa</artifactId>
            <version>2.4.1</version>
        </dependency>

The test basically accesses the database to read the data from one table, and insert it into another. I forgot to say but I’m using JPA and Hibernate in the application in the data access part. And in the case of tests I am also using Dbunit and HSQLDB in memory. During the tests I use CDI to inject (@Inject) the Entitymanager and a DAO.

Thank you.

  • 2

    You can give more information about what your unit test tries to do?

  • It basically accesses the database to read data from one table, and insert it into another. I forgot to tell you but I am using JPA and Hibernate in the application. E in the case of Dbunit and HSQLDB in memory.

2 answers

2

This question is very old, but I’m going through this problem right now and I thought I’d better record an answer.

Investigating I realized that the problem is a change in the order of events marked by the Aftershutdownproccess interface when Oracle JDK 8 is used.

More specifically, in Oracle JDK8 the method: Customcontextbootstrap#terminateContexts runs before Sebootstrap#removeContexts. With Oracle JDK7 the opposite occurs.

Apparently for the execution of Demoiseillerunner, it is not necessary for Sebootstrap#removeContexts to be executed since Customcontextbootstrap#terminateContexts clears the contexts. I believe it is not possible to remove the Systener from Sebootstrap#removeContexts programmatically or declaratively without changing the Demoiseille code itself.

So the workaround I’m using is to use a Fork of the Demoisellerunner class and do not trigger the event, but directly run Customcontextbootstrap#terminateContexts after executing the last test method:


import org.jboss.weld.environment.se.Weld;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;

import br.gov.frameworkdemoiselle.internal.bootstrap.CustomContextBootstrap;
import br.gov.frameworkdemoiselle.lifecycle.AfterShutdownProccess;
import br.gov.frameworkdemoiselle.lifecycle.AfterStartupProccess;
import br.gov.frameworkdemoiselle.util.Beans;

public class CustomDemoiselleRunner extends BlockJUnit4ClassRunner {

    private Integer testsLeft;

    public CustomDemoiselleRunner(Class testClass) throws InitializationError {
        super(testClass);
        this.testsLeft = this.testCount();
    }

    @Override
    protected void runChild(FrameworkMethod method, RunNotifier notifier) {
        super.runChild(method, notifier);

        if (--this.testsLeft == 0) {
            this.shutdown();
        }
    }

    @Override
    public void run(RunNotifier notifier) {
        Weld weld = new Weld();
        weld.initialize();

        this.startup();
        super.run(notifier);

        weld.shutdown();
    }

    protected Object createTest() throws Exception {
        return Beans.getReference(getTestClass().getJavaClass());
    }

    private void startup() {
        Beans.getBeanManager().fireEvent(new AfterStartupProccess() {
        });
    }

    private void shutdown() {
        Beans.getReference(CustomContextBootstrap.class).terminateContexts(new AfterShutdownProccess() {
        });;
    }


}

Obviously there is the problem of not triggering some event possibly necessary for the correct shutdown of Demoiselle, but it seems to work until there is some definitive solution.

0

Did you use some Demoiselle archetype to create the application? Which IDE is Eclipse and which version? It would have to send the code of the complete test class?

  • As my comment, the error is linked to JDK version 8 (1.8.x). When this br.gov.frameworkdemoiselle.internal.bootstrap.SeBootstrap.removeContexts method executes a context deactivation, they are null. The implementation for version 2.4.x has been modified, so those using version 2.3.x of Demoiselle do not face this problem. The solution for now is to use version 7 (1.7.x) of JDK. Or wait for the solution for the "bug".
  • No Demoiselle archetype was used to create the application. I am using the eclipse version Mars. I would have to assemble an example of code, generating the same error, because what I have I cannot provide. As I didn’t have time to generate this example, I answered the other questions and will soon provide an example code. Thank you.

  • Okay. But I have a few more questions: what is the OS you are using, (linux, windows)? What about the JDK version (7 or 8)? I recently noticed a problem similar to this in version 8 of JDK in windows, but there are still some tests to confirm if it is even the version of JDK and if it is also/or related to the OS.

  • I am using Windows 8 and JDK 8. Thank you.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.