19

I have a classpath issue.

  • Background: Building and running a Spring WebApp.
  • Originally it was one big project including dao/service/controller/webapp.
  • I have just broken my project into a maven module project essentially splitting the webapp from the dao and service layers.
  • Now my webapp junit tests do not run.
  • The junit code has not changed and I don't think the dependencies have changed (albeit shifted around).
  • Spring-test is in my local repository.
  • Spring-test is in my unit test runtime classpath (used mvn debug logging to check)
  • I have no other classpath issues. All dao module tests run fine

However, I get

java.lang.NoClassDefFoundError: Could not initialize class org.springframework.test.context.junit4.SpringJUnit4ClassRunner. 

I will post my parent and child pom.xml. If anyone has a suggestion, I'd be very grateful.

Parent Pom.xml

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>jake</groupId> <artifactId>prototype3</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>pom</packaging> <modules> <module>prototype3.model</module> <module>prototype3.service</module> <module>prototype3.testadmin.webapp</module> </modules> <properties> <spring.version>4.1.6.RELEASE</spring.version> <thymeleaf.version>2.1.4.RELEASE</thymeleaf.version> <webflow.version>2.4.0.RELEASE</webflow.version> <internalrepo.dir>C:\Users\jake\_servers\internalRepository</internalrepo.dir> </properties> <distributionManagement> <repository> <id>internal.repo</id> <name>Temporary Staging Repository</name> <url>file://${internalrepo.dir}</url> </repository> </distributionManagement> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> </dependency> <!-- Spring Web Flow --> <dependency> <groupId>org.springframework.webflow</groupId> <artifactId>spring-webflow</artifactId> <version>${webflow.version}</version> <exclusions> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> </exclusion> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> </exclusion> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> </exclusion> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> </exclusion> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> </exclusion> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> </exclusion> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> </exclusion> <exclusion> <groupId>org.springframework.webflow</groupId> <artifactId>spring-js</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.webflow</groupId> <artifactId>spring-js</artifactId> <version>2.4.1.RELEASE</version> <exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> </exclusion> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> </exclusion> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> </exclusion> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> </exclusion> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> </exclusion> </exclusions> </dependency> <!-- javax --> <dependency> <groupId>javax.el</groupId> <artifactId>javax.el-api</artifactId> <version>2.2.4</version> </dependency> <!-- Spring ORM support --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>${spring.version}</version> </dependency> <!-- -hibernate --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>4.3.10.Final</version> <exclusions> <exclusion> <groupId>org.javassist</groupId> <artifactId>javassist</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>9.4-1200-jdbc41</version> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> </exclusion> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.14</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-c3p0</artifactId> <version>4.3.10.Final</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.1.3.Final</version> </dependency> <!-- Hibernate uses slf4j for logging, for our purposes here use the simple backend --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>1.7.12</version> </dependency> <dependency> <groupId>org.javassist</groupId> <artifactId>javassist</artifactId> <version>3.19.0-GA</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> <scope>runtime</scope> </dependency> <dependency> <groupId>taglibs</groupId> <artifactId>standard</artifactId> <version>1.1.2</version> <scope>runtime</scope> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-collections4</artifactId> <version>4.0</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.18.1</version> <exclusions> <exclusion> <groupId>junit</groupId> <artifactId>junit</artifactId> </exclusion> <exclusion> <groupId>org.codehaus.plexus</groupId> <artifactId>plexus-utils</artifactId> </exclusion> <exclusion> <groupId>org.apache.maven</groupId> <artifactId>maven-artifact</artifactId> </exclusion> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </exclusion> <exclusion> <groupId>org.codehaus.plexus</groupId> <artifactId>plexus-container-default</artifactId> </exclusion> <exclusion> <groupId>commons-httpclient</groupId> <artifactId>commons-httpclient</artifactId> </exclusion> </exclusions> <type>maven-plugin</type> <scope>test</scope> </dependency> <!-- Json --> <dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId> <version>2.4.3</version> </dependency> <!-- thymeleaf --> <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf-spring4</artifactId> <version>${thymeleaf.version}</version> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf</artifactId> <version>${thymeleaf.version}</version> <exclusions> <exclusion> <groupId>org.javassist</groupId> <artifactId>javassist</artifactId> </exclusion> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thymeleaf-extras-tiles2</artifactId> <version>2.1.1.RELEASE</version> <exclusions> <exclusion> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf</artifactId> </exclusion> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </exclusion> <exclusion> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thymeleaf-extras-tiles2-spring4</artifactId> <version>2.1.1.RELEASE</version> <exclusions> <exclusion> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf-spring4</artifactId> </exclusion> <exclusion> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf</artifactId> </exclusion> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.10</version> </dependency> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.1</version> </dependency> <!-- Our Own--> <dependency> <groupId>jake</groupId> <artifactId>prototype3.model</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <dependency> <groupId>jake</groupId> <artifactId>prototype3.service</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> </dependencies> </dependencyManagement> </project> 

Child Pom

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>jake</groupId> <artifactId>prototype3</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <artifactId>prototype3.testadmin.webapp</artifactId> <properties> <deploy.directory>C:\Users\jake\_servers\tc8\webapps</deploy.directory> <deploy.name>prototype3</deploy.name> <l4j.test>C:\Users\jake\__workspace\prototype3\prototype3.testadmin.webapp\src\main\resources</l4j.test> <webinf.dir>C:\Users\jake\__workspace\prototype3\prototype3.testadmin.webapp\WebContent\WEB-INF</webinf.dir> <devroot.directory>C:\Users\jake\__workspace\prototype3\prototype3.testadmin.webapp\</devroot.directory> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> </dependency> <!-- Spring Web Flow --> <dependency> <groupId>org.springframework.webflow</groupId> <artifactId>spring-webflow</artifactId> </dependency> <dependency> <groupId>org.springframework.webflow</groupId> <artifactId>spring-js</artifactId> </dependency> <!-- javax --> <dependency> <groupId>javax.el</groupId> <artifactId>javax.el-api</artifactId> </dependency> <!-- Spring ORM support --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> </dependency> <dependency> <groupId>org.javassist</groupId> <artifactId>javassist</artifactId> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>taglibs</groupId> <artifactId>standard</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-collections4</artifactId> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <type>maven-plugin</type> <scope>test</scope> </dependency> <!-- Json --> <dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId> </dependency> <!-- thymeleaf --> <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf-spring4</artifactId> </dependency> <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf</artifactId> </dependency> <dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thymeleaf-extras-tiles2</artifactId> </dependency> <dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thymeleaf-extras-tiles2-spring4</artifactId> </dependency> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> </dependency> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> </dependency> <!-- Our own --> <dependency> <groupId>jake</groupId> <artifactId>prototype3.model</artifactId> </dependency> <dependency> <groupId>jake</groupId> <artifactId>prototype3.service</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.3</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <plugin> <artifactId>maven-war-plugin</artifactId> <version>2.6</version> <configuration> <warSourceDirectory>WebContent</warSourceDirectory> <failOnMissingWebXml>false</failOnMissingWebXml> <outputDirectory>${deploy.directory}</outputDirectory> <webResources> <!-- <resource> <directory>src\main\resources</directory> </resource> --> </webResources> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-enforcer-plugin</artifactId> <version>1.4</version> <executions> <execution> <id>enforce</id> <configuration> <rules> <DependencyConvergence /> </rules> </configuration> <goals> <goal>enforce</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.18.1</version> <configuration> <includes> <include>**/A01TestSuite.java</include> <include>**/ServiceTestSuite.java</include> <include>**/ZFlowTestSuite.java</include> </includes> <additionalClasspathElements> <additionalClasspathElement>${webinf.dir}</additionalClasspathElement> </additionalClasspathElements> <systemPropertyVariables> <log4j.configuration>file:${l4j.test}/log4j.test.properties</log4j.configuration> </systemPropertyVariables> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-clean-plugin</artifactId> <version>2.6.1</version> <configuration> <followSymLinks>false</followSymLinks> <filesets> <fileset> <directory>${deploy.directory}/${deploy.name}</directory> <includes> <include>**/*</include> </includes> </fileset> <fileset> <directory>${devroot.directory}/target</directory> <includes> <include>**/*</include> </includes> </fileset> <fileset> <directory>${deploy.directory}</directory> <includes> <include>${deploy.name}.war</include> <include>${deploy.name}</include> </includes> </fileset> </filesets> </configuration> </plugin> </plugins> <finalName>${deploy.name}</finalName> </build> </project> 

UPDATE

Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.002 sec <<< FAILURE! - in jake.prototype2.test.testrunner.ServiceTestSuite initializationError(jake.prototype2.test.service.UserAdminServiceTest) Time elapsed: 0.002 sec <<< ERROR! java.lang.NoClassDefFoundError: Could not initialize class org.springframework.test.context.junit4.SpringJUnit4ClassRunner at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) at java.lang.reflect.Constructor.newInstance(Unknown Source) at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:104) at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:86) at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59) at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26) at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59) at org.junit.runners.model.RunnerBuilder.runners(RunnerBuilder.java:101) at org.junit.runners.model.RunnerBuilder.runners(RunnerBuilder.java:87) at org.junit.runners.Suite.(Suite.java:10

6
  • can you run mvn dependency:tree to verify if spring-test is actually there in the final effective POM of your project? Commented Nov 27, 2015 at 6:51
  • It's there. Also, all code compiles, but tests don't run. Thanks for the tip, though. That's a very useful mvn utility to know about Commented Nov 27, 2015 at 8:15
  • 1
    I have recreated the same structure locally, except the model and service modules, and created a dummy junit test with @RunWith(SpringJUnit4ClassRunner.class) and it runs fine, no NoClassDefFoundError error. Are you sure it comes from the webapp module and not from the service or model module? In the parent you correctly set dependencies on dependenciesManagement, which also means you need to re-declare them in each child module (as you do in the webapp one) otherwise it will not be part of the module classpath. I would suggest to check the dependencies of other modules as well. Commented Nov 27, 2015 at 9:13
  • Yes, I am absolutley certain this is coming from the webapp module Commented Nov 27, 2015 at 15:58
  • We need to see the full stack trace; otherwise, it's just a stab in the dark. In other words, what class definition is not found? Commented Nov 27, 2015 at 22:27

7 Answers 7

28

I dont know why but in my case spring-boot-starter-test comes with junit 4.10 and I find that is compiled with 4.12, so after add

 <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> 

Works fine. Maybe a misconfiguration in pom of spring-boot

Sign up to request clarification or add additional context in comments.

2 Comments

Solved my problem.
In addition to this I also had to bump slf4j to <slf4j.version>1.7.21</slf4j.version>
21

In a comment you've said that project compiles, but tests don't run. Maven-surefire-plugin may be the culpit (as it was in my case). I was getting the same error, but after a little digging I knew that:

java.lang.NoClassDefFoundError: Could not initialize class org.springframework.test.context.junit4.SpringJUnit4ClassRunner. 

was caused by:

java.lang.IllegalStateException: SpringJUnit4ClassRunner requires JUnit 4.12 or higher. at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.<clinit> 

which was thrown because maven-surefire-plugin wasn't picking test framework provider from the classpath but instead supplied its own outdated junit provider.

I get rid of the error by specifying JUnit artifact name:

<plugins> ... <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>{your.surefire.version}</version> <configuration> <junitArtifactName> junit:junit:{your.junit.version} </junitArtifactName> </configuration> </plugin> ... </plugins> 

1 Comment

This is the fix for spring boot 1.4.3.RELEASE.
8

For anyone looking at this I had a similar problem and the issue had to do with a logging impl conflict that was pulled in from maven transitive dependencies in spring boot. Once I excluded spring-boot-starter-logging it fixed the issue.

SpringJUnit4ClassRunner most likely wasn't able to initialize in the classloader from the logging conflict and the NoClassDefFoundError was thrown at another point in the code because of that.

2 Comments

awesome. When I tried to run the failing testcase in Intellij it told me about the 'java.lang.IllegalStateException: Detected both log4j-over-slf4j.jar AND bound slf4j-log4j12.jar on the class path' And hidden in the stacktrace it showed: 'at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.<clinit>(SpringJUnit4ClassRunner.java:96) at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:104)'
I imported a dependency with it's own logging dependencies which screwed up the SpringJUnit4ClassRunner. Excluding them helped.
0

I found a solution, not an answer to my question.

The solution was to break the project up in stages.

  • First, I created three standalone projects and ran the relevant unit tests on each. (Obviously this has to be done in the correct order to ensure dependency)

  • Second, I created the parent pom and depency management.

  • Third, I brought each standalone project under the paren one by one. I gradually reduced the child pom dependencies through an iterative series of testing.

I still have no idea why the above structure failed. However, since everything now works, there is no reason to continue reduction until I finally break my webapp again.

Comments

0

I recently encountered this. I just updated the version from 3.0.7.RELEASE to 3.1.1.RELEASE.

Comments

0

I encountered the same error in Spring Boot. I just changed the spring-boot-starter-parent version from 1.5.6.RELEASE to 1.5.10.RELEASED.

This spring boot version already contains the class below:

org.springframework.test.context.junit4.SpringJUnit4ClassRunner

Comments

0

I used springmockk dependency, which caused those errors. I fixed it by using a older version of it, because the newest version wasn't compatible with my older Springboot version.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.