'java.lang.NoClassDefFoundError with REST-assured 3.0.0 and Java 11 (not observed with Java 8)

Here's what my build.gradle file looks like:

plugins {
    id 'java'
    id "com.github.lkishalmi.gatling" version "0.7.0"
    id 'application'
}

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {
    compile group: 'io.rest-assured', name: 'rest-assured', version: '3.0.0'
}

task runTests(type: Test) {
    useTestNG() {
        useDefaultListeners = true
        suites 'src/test/testng.xml'
    }
}

Here's what my testng.xml looks like:

<!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd" >
<suite name="my-test-suite">
    <test name="myTest">
        <classes>
            <class name="tests.SomeTests">
                <methods>
                    <include name="testVerifySomething"/>
                </methods>
            </class>
        </classes>
    </test>
</suite>

The java.lang.NoClassDefFoundError error originates from the SomeTests class at the line where there is a call to a static method from another class SomeUtils from another package utils.

Here's the full trace:

java.lang.NoClassDefFoundError: javax.xml.bind.JAXBException
    at io.restassured.config.ObjectMapperConfig.<init>(ObjectMapperConfig.java:49)
    at io.restassured.config.RestAssuredConfig.<init>(RestAssuredConfig.java:41)
    at io.restassured.RestAssured.<clinit>(RestAssured.java:420)
    at utils.SomeUtils.createUser(SomeUtils.java:13)
    at tests.SomeTests.createUser(SomeTests.java:63)
    at tests.SomeTests.testCreateUsers(SomeTests.java:47)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
    at org.testng.internal.Invoker.invokeMethod(Invoker.java:583)
    at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:719)
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:989)
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
    at org.testng.TestRunner.privateRun(TestRunner.java:648)
    at org.testng.TestRunner.run(TestRunner.java:505)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
    at org.testng.SuiteRunner.run(SuiteRunner.java:364)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1137)
    at org.testng.TestNG.runSuites(TestNG.java:1049)
    at org.testng.TestNG.run(TestNG.java:1017)
    at org.gradle.api.internal.tasks.testing.testng.TestNGTestClassProcessor.runTests(TestNGTestClassProcessor.java:139)
    at org.gradle.api.internal.tasks.testing.testng.TestNGTestClassProcessor.stop(TestNGTestClassProcessor.java:89)
    at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:61)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
    at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
    at com.sun.proxy.$Proxy2.stop(Unknown Source)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.stop(TestWorker.java:131)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:155)
    at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:137)
    at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:404)
    at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
    at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
    at java.base/java.lang.Thread.run(Thread.java:825)
Caused by: java.lang.ClassNotFoundException: javax.xml.bind.JAXBException
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:768)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:1052)
    ... 56 more

The directory structure looks like this:

build.gradle
src
--test
----java
------tests
        SomeTests
------utils
        SomeUtils

What I've tried so far:

  1. Add runtime files('src/test/java/utils') inside the dependencies section of my build.gradle.
  2. Add compile files('src/test/java/utils') inside the dependencies section of my build.gradle.
  3. Add both 1 & 2 inside the dependencies section of my build.gradle.

EDIT: After some trial and errors, it seems the Java version is the cause here since the issue is seen with Java 11 and not with Java 8. I verified this behaviour on multiple machines just to ensure there's nothing specific on my machine.



Solution 1:[1]

You have not specified exactly which class is not found! Complete stackstrace will help.

Nevertheless, as you mentioned it worked on jdk8 which means there is high probability you are using/depending on some class which is removed after jdk9 like jaxb, javax etc.

If that is the case, you have couple of options here:

  • run your app/test with following jvmopts setting --add-modules=java.xml.bind,java.activation or create .jvmopts file with above line at root directory of your project
  • add explicit dependency in you build based on which class is missing

Solution 2:[2]

you can try changing the version of the rest assured dependency . from 3.0.0 to 4.1.2

<dependency>
        <groupId>io.rest-assured</groupId>
        <artifactId>rest-assured</artifactId>
        <version>4.1.2</version>
</dependency>

it will help

Solution 3:[3]

It is because the JAXB library (Java Architecture for XML Binding) is missing in the classpath. JAXB is included in Java SE 10 or older, but it is removed from Java SE from Java 11 or newer –moved to Java EE under Jakarta EE project. That means if you encounter JAXBException error, it’s very much likely that you are using Java 11 or newer for your project. So to fix this error, you have to options:

  1. Use older Java versions like JDK 8, 9, or 10 which still include the JAXB library by default. Or:
  2. Specify an additional dependency in your project’s pom.xml file as follows:
    <dependency>
        <groupId>javax.xml.bind</groupId>
        <artifactId>jaxb-api</artifactId>
        <version>2.3.0</version>
    </dependency>

In case you don’t use Maven https://mvnrepository.com/artifact/javax.xml.bind/jaxb-api/2.3.0

Solution 4:[4]

The "root" of your code files ie test files in this case should be src/test/java. So, you could try adding compile files('src/test/java') to yourtestClasspath` variable.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Pritam Kadam
Solution 2 Saurabh Verma
Solution 3
Solution 4 Vijay Raghavan Aravamudhan