Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Class org.assertj.core.error.AssertJMultipleFailuresError declares multiple JSON fields named heading - Cucumber + SoftAssertions #37

Closed
francislainy opened this issue Jan 22, 2024 · 7 comments

Comments

@francislainy
Copy link

francislainy commented Jan 22, 2024

We keep getting this error in our cucumber tests.

java.lang.IllegalArgumentException: class org.assertj.core.error.AssertJMultipleFailuresError declares multiple JSON fields named heading

at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:172)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:102)
	at com.google.gson.Gson.getAdapter(Gson.java:489)
	
	
	.....
	
	at com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter.finishReport(ExtentCucumberAdapter.java:300)
	at com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter.access$600(ExtentCucumberAdapter.java:62)
	at com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter$8.receive(ExtentCucumberAdapter.java:136)
	at com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter$8.receive(ExtentCucumberAdapter.java:133)
	at io.cucumber.core.eventbus.AbstractEventPublisher.send(AbstractEventPublisher.java:51)
	at io.cucumber.core.eventbus.AbstractEventBus.send(AbstractEventBus.java:12)
	at io.cucumber.core.runtime.SynchronizedEventBus.send(SynchronizedEventBus.java:47)
	at io.cucumber.core.runtime.CucumberExecutionContext.emitTestRunFinished(CucumberExecutionContext.java:131)
	at io.cucumber.core.runtime.CucumberExecutionContext.finishTestRun(CucumberExecutionContext.java:118)
	at io.cucumber.junit.Cucumber$FinishTestRun.evaluate(Cucumber.java:250)

It seems to be related to Gson and or Assert Core when using SoftAssertions. We don't use Gson directly in our tests, but it comes as a transitive dependency and when trying to exclude it, I would be getting other errors and the tests won't run.

I have these versions and dependencies:

 <properties>
        <java.version>11</java.version>
        <maven.compiler.source>${java.version}</maven.compiler.source>
        <maven.compiler.target>${java.version}</maven.compiler.target>

        <maven-compiler-plugin.version>3.8.0</maven-compiler-plugin.version>
        <maven-surefire-plugin.version>3.0.0-M5</maven-surefire-plugin.version>

        <spring-boot.version>2.6.6</spring-boot.version>
        <cucumber.version>7.2.3</cucumber.version>

        <extent.report.version>1.3.0</extent.report.version>
        <rally.api.version>1.3</rally.api.version> //Custom dependency

    </properties>
	
	
  <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>io.cucumber</groupId>
                <artifactId>cucumber-bom</artifactId>
                <version>${cucumber.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
	
	 <dependencies>

        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-spring</artifactId>
        </dependency>

        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-junit</artifactId>
        </dependency>

        <dependency>
            <groupId>tech.grasshopper</groupId> // Uses Gson
            <artifactId>extentreports-cucumber7-adapter</artifactId>
            <version>${extent.report.version}</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.jupiter</groupId>
                    <artifactId>junit-jupiter-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.apache.logging.log4j</groupId>
                    <artifactId>log4j-to-slf4j</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>com.mycustom.cs</groupId>
            <artifactId>cs-rally-api</artifactId> // Uses Gson
            <version>${rally.api.version}</version>
        </dependency>

        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.httpcomponents.core5</groupId>
            <artifactId>httpcore5</artifactId>
        </dependency>

    </dependencies>

This is a sample for how we are doing the assertions:

   @Given("I debug test")
    public void iDebug() {
        SoftAssertions softAssertions = new SoftAssertions();
        softAssertions.assertThat(1).isEqualTo(2);
        softAssertions.assertThat(2).isEqualTo(3);
        softAssertions.assertAll();
    }
    }

Tried with the latest versions for Spring Boot, Cucumber and ExtentReports,

 <properties>

        <java.version>17</java.version>
        <maven.compiler.source>${java.version}</maven.compiler.source>
        <maven.compiler.target>${java.version}</maven.compiler.target>

        <maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
        <maven-surefire-plugin.version>3.1.0</maven-surefire-plugin.version>

        <spring-boot.version>3.2.1</spring-boot.version>
        <cucumber.version>7.12.0</cucumber.version>

        <extent-report.version>1.14.0</extent-report.version>
        <rally-api.version>1.3</rally-api.version>
        <jackson-databind-nullable.version>0.2.6</jackson-databind-nullable.version>
    </properties>

but the error still persists:

java.lang.IllegalArgumentException: Class org.assertj.core.error.AssertJMultipleFailuresError declares multiple JSON fields named 'heading'; conflict is caused by fields org.assertj.core.error.AssertJMultipleFailuresError#heading and org.opentest4j.MultipleFailuresError#heading

at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:302)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:130)
	at com.google.gson.Gson.getAdapter(Gson.java:556)
	at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:55)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:196)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:368)
	at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:70)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:196)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:368)
	at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:70)
	at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:97)
	at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:61)
	at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:70)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:196)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:368)
	at com.google.gson.Gson$FutureTypeAdapter.write(Gson.java:1371)
	at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:70)
	at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:97)
	at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:61)
	at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:70)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:196)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:368)
	at com.google.gson.Gson$FutureTypeAdapter.write(Gson.java:1371)
	at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:70)
	at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:97)
	at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:61)
	at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:70)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:196)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:368)
	at com.google.gson.internal.bind.ObjectTypeAdapter.write(ObjectTypeAdapter.java:183)
	at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:70)
	at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:97)
	at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:61)
	at com.google.gson.Gson.toJson(Gson.java:842)
	at com.google.gson.Gson.toJson(Gson.java:812)
	at com.google.gson.Gson.toJson(Gson.java:783)
	at com.aventstack.extentreports.reporter.JsonFormatter.flush(JsonFormatter.java:57)
	at com.aventstack.extentreports.reporter.JsonFormatter$1.onNext(JsonFormatter.java:37)
	at com.aventstack.extentreports.reporter.JsonFormatter$1.onNext(JsonFormatter.java:30)
	at io.reactivex.rxjava3.subjects.PublishSubject$PublishDisposable.onNext(PublishSubject.java:310)
	at io.reactivex.rxjava3.subjects.PublishSubject.onNext(PublishSubject.java:226)
	at com.aventstack.extentreports.ReactiveSubject.onFlush(ReactiveSubject.java:83)
	at com.aventstack.extentreports.AbstractProcessor.onFlush(AbstractProcessor.java:95)
	at com.aventstack.extentreports.ExtentReports.flush(ExtentReports.java:279)
	at com.aventstack.extentreports.service.ExtentService.flush(ExtentService.java:47)
	at com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter.finishReport(ExtentCucumberAdapter.java:301)
	at com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter$8.receive(ExtentCucumberAdapter.java:137)
	at com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter$8.receive(ExtentCucumberAdapter.java:134)
	at io.cucumber.core.eventbus.AbstractEventPublisher.send(AbstractEventPublisher.java:51)
	at io.cucumber.core.eventbus.AbstractEventBus.send(AbstractEventBus.java:12)
	at io.cucumber.core.runtime.SynchronizedEventBus.send(SynchronizedEventBus.java:47)
	at io.cucumber.core.runtime.CucumberExecutionContext.emitTestRunFinished(CucumberExecutionContext.java:118)
	at io.cucumber.core.runtime.CucumberExecutionContext.finishTestRun(CucumberExecutionContext.java:105)
	at io.cucumber.junit.platform.engine.CucumberEngineExecutionContext.finishTestRun(CucumberEngineExecutionContext.java:126)
	at io.cucumber.junit.platform.engine.CucumberEngineDescriptor.ifChildren(CucumberEngineDescriptor.java:51)
	at io.cucumber.junit.platform.engine.CucumberEngineDescriptor.cleanUp(CucumberEngineDescriptor.java:36)
	at io.cucumber.junit.platform.engine.CucumberEngineDescriptor.cleanUp(CucumberEngineDescriptor.java:11)

Thank you very much.

@francislainy
Copy link
Author

francislainy commented Jan 22, 2024

@grasshopper7
Copy link
Owner

This seems to be due to the json formatter report generation. Can you give it a try by setting the extent.reporter.json.start configuration to false.

Can you raise this issue in the extent report repo - https://github.com/extent-framework/extentreports-java/issues.

@francislainy
Copy link
Author

This seems to be due to the json formatter report generation. Can you give it a try by setting the extent.reporter.json.start configuration to false.

Can you raise this issue in the extent report repo - https://github.com/extent-framework/extentreports-java/issues.

Thank you for looking into this so quickly.

As suggested, the issue is raised here: extent-framework/extentreports-java#424

I can try your suggestion when I'm again with the other laptop where my code is.

@francislainy
Copy link
Author

Hi

This seems to be due to the json formatter report generation. Can you give it a try by setting the extent.reporter.json.start configuration to false.

Can you raise this issue in the extent report repo - https://github.com/extent-framework/extentreports-java/issues.

Hi again, I've just tried your suggestion and it seems to fix the issue:

extent.reporter.json.start=false

I'll comment the same on the other issue I've created. Should I close both issues now?

@francislainy
Copy link
Author

Hi

This seems to be due to the json formatter report generation. Can you give it a try by setting the extent.reporter.json.start configuration to false.
Can you raise this issue in the extent report repo - https://github.com/extent-framework/extentreports-java/issues.

Hi again, I've just tried your suggestion and it seems to fix the issue:

extent.reporter.json.start=false

I'll comment the same on the other issue I've created. Should I close both issues now?

Also, if you'd like to add this as an answer to Stack Overflow, I can accept that.
Thanks very much.

@grasshopper7
Copy link
Owner

You can close the issue here but the other one is valid which needs to be investigated. Setting the json reporter to false is a workaround at best and will not work for users who need that report.

This needs to be fixed in the main extent report code, to which I do not have direct commit access.

Just a shot in the dark but it may be due to java 17 because as far as I know extent code has been tested till java 11.

@francislainy
Copy link
Author

You can close the issue here but the other one is valid which needs to be investigated. Setting the json reporter to false is a workaround at best and will not work for users who need that report.

This needs to be fixed in the main extent report code, to which I do not have direct commit access.

Just a shot in the dark but it may be due to java 17 because as far as I know extent code has been tested till java 11.

Thank you. I'll close it.
I wouldn't think it to do with Java 11 and 17 as I've got the same issue for both versions.
But maybe something with Spring Boot and Spring as when our project was declaring the individual dependencies and using Spring instead of getting the dependencies from Spring Boot and dependency management, this issue wasn't happening.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants