尝试使用Spring运行jUnit测试时出现NoSuchFieldError错误

12

到目前为止,我有两个测试。一个只使用jUnit框架并且正常工作。另一个使用spring-test库,并且每次尝试运行它时都会创建此异常。对于可能导致问题的原因有何想法吗?

错误

java.lang.NoSuchFieldError: NULL
at org.junit.runners.ParentRunner.<init>(ParentRunner.java:48)
at org.junit.runners.BlockJUnit4ClassRunner.<init>(BlockJUnit4ClassRunner.java:59)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.<init>(SpringJUnit4ClassRunner.java:104)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:27)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.<init>(JUnit4TestReference.java:32)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestClassReference.<init>(JUnit4TestClassReference.java:25)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:41)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:31)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:452)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

Maven测试依赖项

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.7</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>${org.springframework.version}</version>
    <scope>test</scope>
</dependency>

依赖树

[INFO] [dependency:tree {execution: default-cli}]
[INFO] fake:war:1.0-SNAPSHOT
[INFO] +- log4j:log4j:jar:1.2.16:compile
[INFO] +- org.springframework:spring-web:jar:3.0.5.RELEASE:compile
[INFO] |  +- aopalliance:aopalliance:jar:1.0:compile
[INFO] |  +- org.springframework:spring-beans:jar:3.0.5.RELEASE:compile
[INFO] |  +- org.springframework:spring-context:jar:3.0.5.RELEASE:compile
[INFO] |  |  +- org.springframework:spring-aop:jar:3.0.5.RELEASE:compile
[INFO] |  |  +- org.springframework:spring-expression:jar:3.0.5.RELEASE:compile
[INFO] |  |  \- org.springframework:spring-asm:jar:3.0.5.RELEASE:compile
[INFO] |  \- org.springframework:spring-core:jar:3.0.5.RELEASE:compile
[INFO] |     \- commons-logging:commons-logging:jar:1.1.1:compile
[INFO] +- commons-codec:commons-codec:jar:1.4:compile
[INFO] +- org.glassfish:javax.faces:jar:2.1.3:compile
[INFO] +- org.richfaces.ui:richfaces-components-ui:jar:4.0.0.Final:compile
[INFO] |  +- org.richfaces.ui:richfaces-components-api:jar:4.0.0.Final:compile
[INFO] |  \- org.richfaces.core:richfaces-core-api:jar:4.0.0.Final:compile
[INFO] +- org.richfaces.core:richfaces-core-impl:jar:4.0.0.Final:compile
[INFO] |  +- net.sourceforge.cssparser:cssparser:jar:0.9.5:compile
[INFO] |  |  \- org.w3c.css:sac:jar:1.3:compile
[INFO] |  \- com.google.guava:guava:jar:r08:compile
[INFO] +- org.hibernate:hibernate-validator:jar:4.2.0.Final:compile
[INFO] |  \- org.slf4j:slf4j-api:jar:1.6.1:compile
[INFO] +- javax.validation:validation-api:jar:1.0.0.GA:compile
[INFO] +- javax.xml.bind:jaxb-api:jar:2.2.2:compile
[INFO] |  +- javax.xml.stream:stax-api:jar:1.0-2:compile
[INFO] |  \- javax.activation:activation:jar:1.1:compile
[INFO] +- com.sun.xml.bind:jaxb-impl:jar:2.2.2:compile
[INFO] +- javax.servlet:jstl:jar:1.1.2:compile
[INFO] +- junit:junit:jar:4.7:test
[INFO] +- org.springframework:spring-test:jar:3.0.5.RELEASE:test
[INFO] +- javax.servlet:jsp-api:jar:2.0:provided
[INFO] \- javax.servlet:servlet-api:jar:2.4:provided

顺便说一下,我在Eclipse中使用自定义类加载器运行时遇到了这个问题(没有使用Spring)。 - Gilead
5个回答

20

你是否在使用旧版本的Eclipse(Galileo或更早版本)? 或者是旧版本的junit插件? 如果是这样,这可能是问题的原因。ParentRunner正在寻找Sorter.NULL,这是在JUnit 4.5中引入的:

package org.junit.runner.manipulation;

public class Sorter implements Comparator<Description> {
    /**
     * NULL is a <code>Sorter</code> that leaves elements in an undefined order
     */
    public static Sorter NULL= new Sorter(new Comparator<Description>() {
        public int compare(Description o1, Description o2) {
            return 0;
        }});

如果您没有这段代码,那么您可能使用的是4.5版本以下的预发行版。在Eclipse上,按Ctrl-Shift-T,查看是否有多个Sorter类的版本可用,如果有,请确保它们都不是4.5版本以下。此外,在您的项目设置中查看构建路径,如果有JUnit条目(而不是Maven版本),请删除它,然后重试。
编辑:这也可能是由于Maven的传递依赖引起的。也许您的某个库依赖于一个4.5版本以下的JUnit版本。

Eclipse Build Path, JUnit entry


谢谢你提供使用Sorter的提示!在我的情况下,我依赖于一个旧版本的Cobertura,这导致了问题! - alexandroid
@Matthew Farwell 我正在使用带有JUnit4.10的Kepler,并且在Sorter中有以上行,但我仍然遇到“initializationError0 - java.lang.NoSuchFieldError: NULL”。 - yashhy
啊!!你真的救了我的一天...谢谢 - Raju Penumatsa

2

我解决了这个问题,将JUnit升级到4.10版本。原始异常信息如下:

java.lang.NoSuchFieldError: NULL
    at org.junit.runners.ParentRunner.<init>(ParentRunner.java:54)
    at org.junit.runners.BlockJUnit4ClassRunner.<init>(BlockJUnit4ClassRunner.java:55)
    at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl$1.<init>(JUnit45AndHigherRunnerImpl.java:23)
    at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.<init>(JUnit45AndHigherRunnerImpl.java:23)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at org.mockito.internal.runners.util.RunnerProvider.newInstance(RunnerProvider.java:39)
    at org.mockito.internal.runners.RunnerFactory.create(RunnerFactory.java:28)
    at org.mockito.runners.MockitoJUnitRunner.<init>(MockitoJUnitRunner.java:57)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at org.junit.internal.requests.ClassRequest.buildRunner(ClassRequest.java:33)
    at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:28)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.<init>(JUnit4TestReference.java:32)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestClassReference.<init>(JUnit4TestClassReference.java:25)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:41)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:31)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:452)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

1

这看起来是由于您的类路径中有多个不同版本的JUnit依赖项引起的。检查您的类路径(如果您使用的是maven,请执行mvn dependency:tree),然后摆脱旧版本(同样,如果使用maven,请找出哪个直接导入的依赖项进而导入旧的JUnit,并在pom.xml中对该依赖项进行<exclusion>以排除JUnit子依赖项)。此外,您可能还想将实际的JUnit依赖项更新到最新版本,即(至少)4.10。


我添加了依赖树,我只看到一个版本的junit库。此外,4.10版本没有产生任何区别。 - user219882
这是我的问题:junit-dep 4.4 是从 org.jmock:jmock-junit4 的传递依赖项,而我直接依赖于 junit 4.10。 - hertzsprung
可以使用 mvn exclusion,但那是很久以前的事了 ;) - hertzsprung
@hertzsprung,不知道为什么我的排除功能无法正常工作。谢谢。请参见:http://stackoverflow.com/questions/17560153/junit-annotation-not-running/17564130?noredirect=1#17564130 - AnthonyW
@AnthonyW 你的 mvn dependency:tree 命令有没有给你提供任何有用的信息? - hertzsprung
@hertzsprung 使用Eclipse的m2e。所有细节都在相关问题中。简而言之,我在JMock中有一个传递依赖于JUnit-dep,它拒绝被排除,并且不会因为我依赖于JUnit(不同的构件名称)而被省略。 - AnthonyW

1
我曾经遇到过完全相同的问题,后来发现是由 org.jmock:jmock-junit4 的一个传递依赖引起的。当我将它替换为 org.jmock:jmock 时,问题得到了解决。

0

我因为同样的原因遇到了这个错误。但在我的情况下,通过查看我的pom.xml或maven源代码树,我无法看到不同版本的Junits,因为我的项目使用传递依赖(在项目之间)。即项目“A”依赖于项目“B”。所以项目“A”直接引用“B”(来自工作区)。当发生这种情况时,我们将无法确定依赖项中是否存在不同版本的junit。所以我所做的是,关闭项目“B”。从eclipse中删除项目“A”(而不是从工作区中删除)。在项目“A”的源目录中,除了pom、src和svn支持文件夹之外,删除所有文件。重新将文件导入到eclipse中。这解决了问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接