renatoathaydes / spock-reports

This project creates a global extension to Spock to create test reports.
Apache License 2.0
274 stars 68 forks source link

Exception on ReportDataAggregator #253

Closed ralbuh closed 1 year ago

ralbuh commented 1 year ago

Recently we switched to newest java 17 with spring boot 3 (spring 6). This caused the reporting that was working before to start failing.

The following error occurs:

Exception in thread "org.spockframework.runtime.RunContext.stop()" java.lang.NoClassDefFoundError: Could not initialize class com.athaydes.spockframework.report.internal.ReportDataAggregator
        at java.base/java.lang.Class.forName0(Native Method)
        at java.base/java.lang.Class.forName(Class.java:467)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.lambda$createCallStaticSite$2(CallSiteArray.java:63)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:318)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.doPrivileged(CallSiteArray.java:81)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.createCallStaticSite(CallSiteArray.java:61)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallStatic(CallSiteArray.java:53)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callStatic(AbstractCallSite.java:217)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callStatic(AbstractCallSite.java:240)
        at com.athaydes.spockframework.report.template.TemplateReportAggregator.writeOut(TemplateReportAggregator.groovy:59)
        at com.athaydes.spockframework.report.template.TemplateReportAggregator$writeOut.call(Unknown Source)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callSafe(AbstractCallSite.java:104)
        at com.athaydes.spockframework.report.template.TemplateReportCreator.done(TemplateReportCreator.groovy:82)
        at com.athaydes.spockframework.report.IReportCreator$done$0.call(Unknown Source)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callSafe(AbstractCallSite.java:88)
        at com.athaydes.spockframework.report.SpockReportExtension.stop(SpockReportExtension.groovy:73)
        at org.spockframework.runtime.GlobalExtensionRegistry.stopGlobalExtensions(GlobalExtensionRegistry.java:144)
        at org.spockframework.runtime.RunContext.stop(RunContext.java:68)
        at java.base/java.lang.Thread.run(Thread.java:833)

Maven dependencies:

        <dependency>
            <groupId>org.spockframework</groupId>
            <artifactId>spock-core</artifactId>
            <version>2.4-M1-groovy-4.0</version>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>log4j</groupId>
                    <artifactId>log4j</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.spockframework</groupId>
            <artifactId>spock-spring</artifactId>
            <version>2.4-M1-groovy-4.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.groovy</groupId>
            <artifactId>groovy</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.groovy</groupId>
            <artifactId>groovy-templates</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.athaydes</groupId>
            <artifactId>spock-reports</artifactId>
            <version>2.5.0-groovy-4.0</version>
            <scope>test</scope>
            <!-- this avoids affecting current version of Groovy/Spock -->
            <exclusions>
                <exclusion>
                    <groupId>*</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

groovy version is 4.0.12 automatically configured

spockReports config:

spockReports {
  set 'com.athaydes.spockframework.report.IReportCreator': 'com.athaydes.spockframework.report.template.TemplateReportCreator'
  set 'com.athaydes.spockframework.report.template.TemplateReportCreator.specTemplateFile': '/templates/spec-template.adoc'
  set 'com.athaydes.spockframework.report.template.TemplateReportCreator.reportFileExtension': 'adoc'
  set 'com.athaydes.spockframework.report.template.TemplateReportCreator.summaryTemplateFile': '/templates/summary-template.adoc'
  set 'com.athaydes.spockframework.report.template.TemplateReportCreator.summaryFileName': 'index.adoc'
  set 'com.athaydes.spockframework.report.outputDir': 'src/main/asciidoc/spock-reports'
}

Separate html reports per specification are generated in build/spock-reports but after that it's not being aggregated and included in our asciidocs.

Would really appreciate some help since we do like and use the reports.

renatoathaydes commented 1 year ago

Hi @ralbuh . There isn't enough information to know why this is happening. Does the stacktrace you posted have a caused by sub-stacktrace? Given the Template report creator was found (as you got the spec reports), there should be no way the aggregator report creator is not found as it's in the same jar.

You can actually verify that by doing something like jar tf spock-reports.jar | grep Aggregator. If it's there, then there's no reason the JVM shouldn't find it.

renatoathaydes commented 1 year ago

This may have something to do with Java 17 module restrictions, but it's strange because I do test spock-reports on JDK 17 and it works. The report creator is created by reflection... but the class loading the report creator is from the same jar, so it makes no sense that the JVM will not allow that... could it be something related to Groovy's dynamic loading, so it looks like it's Groovy loading the class, not spock-reports classes?

at java.base/java.lang.Class.forName(Class.java:467)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.lambda$createCallStaticSite$2(CallSiteArray.java:63)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:318)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.doPrivileged(CallSiteArray.java:81)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.createCallStaticSite(CallSiteArray.java:61)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallStatic(CallSiteArray.java:53)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callStatic(AbstractCallSite.java:217)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callStatic(AbstractCallSite.java:240)
        at com.athaydes.spockframework.report.template.TemplateReportAggregator.writeOut(TemplateReportAggregator.groovy:59)

Maybe because of the Groovy indirection, you need to open the spock-reports package to the groovy jars... just a hunch but may be worth trying it.

ralbuh commented 1 year ago

By accident I found the problem. Some other project was having one extra dependency and that was working with similar setup. Adding the following dependency fixed the problem:

<dependency>
            <groupId>org.apache.groovy</groupId>
            <artifactId>groovy-json</artifactId>
            <scope>test</scope>
        </dependency>
renatoathaydes commented 1 year ago

Oh interesting... that means that ReportDataAggregator could not be instantiated because it was missing some class from the groovy-json jar... the error should've included that information!