Uploaded image for project: 'Maven Surefire'
  1. Maven Surefire
  2. SUREFIRE-825

NPE in JUnit4TestChecker if org.junit.runner.RunWith class can't be loaded by testClassloader

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • 2.10
    • 2.12.1
    • Junit 4.x support
    • None
    • tycho-surefire OSGi adapter
    • Patch

    Description

      This is a follow up on tycho-surefire bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=369266

      If the class org.junit.runner.RunWith can't be loaded by the test classloader, we get an NPE

      org.apache.maven.surefire.util.SurefireReflectionException: java.lang.reflect.InvocationTargetException; nested exception is java.lang.reflect.InvocationTargetException: null
      java.lang.reflect.InvocationTargetException
      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.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:164)
      at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:110)
      at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:175)
      at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcess(SurefireStarter.java:123)
      at org.eclipse.tycho.surefire.osgibooter.OsgiSurefireBooter.run(OsgiSurefireBooter.java:84)
      at org.eclipse.tycho.surefire.osgibooter.HeadlessTestApplication.run(HeadlessTestApplication.java:21)
      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.eclipse.equinox.internal.app.EclipseAppContainer.callMethodWithException(EclipseAppContainer.java:587)
      at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:198)
      at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
      at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
      at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344)
      at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
      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.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622)
      at org.eclipse.equinox.launcher.Main.basicRun(Main.java:577)
      at org.eclipse.equinox.launcher.Main.run(Main.java:1410)
      at org.eclipse.equinox.launcher.Main.main(Main.java:1386)
      Caused by: java.lang.NullPointerException
      at java.lang.Class.getAnnotation(Class.java:3027)
      at org.apache.maven.surefire.common.junit4.JUnit4TestChecker.isValidJUnit4Test(JUnit4TestChecker.java:63)
      at org.apache.maven.surefire.common.junit4.JUnit4TestChecker.accept(JUnit4TestChecker.java:52)
      at org.apache.maven.surefire.util.DefaultDirectoryScanner.locateTestClasses(DefaultDirectoryScanner.java:80)
      at org.apache.maven.surefire.junit4.JUnit4Provider.scanClassPath(JUnit4Provider.java:174)
      at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:83)
      ... 28 more

      This can happen in an OSGi classloader environment where classloading/visibility is controlled down to the package level.
      A test OSGi bundle may well only import package org.junit (containing the Test annotation, via MANIFEST header "Import-Package: org.junit"), but not package org.junit.runner.
      Thus org.junit.runner.RunWith can't be loaded by the test classloader and the runWith member in JUnit4TestChecker is null.

      Attached patch gracefully handles the null case simply by adding a null check.
      IMHO we can safely ignore the case where the RunWith class can't be loaded because if it can't be loaded, the test was not able to reference it at design time either, so it can't be annotated with @RunWith.

      Providing a standalone test case for this is hard as it only happens in an OSGi classloader environment...
      The sample project attached to the original tycho-surefire issue above demonstrates the problem. ('mvn clean integration-test' to reproduce)

      Attachments

        Activity

          People

            krosenvold Kristian Rosenvold
            jan.sievers Jan Sievers
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: