Search code examples
javagrailsgroovyjvm

Missing resolveStrategy breaks DSL when executed from runnable jar


I'm using the Groovy Spreadsheet Builder within one of my Grails projects to export some data as Excel file.

Everything works great until I create a runnable jar (using gradle assemble) and use this.

I'm using the builder within a service like this:

class ExcelService {
    ...
    void export(OutputStream outputStream) {
       ...
       PoiSpreadsheetBuilder.create(outputStream).build {
          apply ExcelStylesheet
          ...
       } 
    }
    ...
}

When I try to export my data from the app started using the generated jar I will get the following MissingMethodException:

groovy.lang.MissingMethodException: No signature of method: my.package.ExcelService.apply() is applicable for argument types: (java.lang.Class)

The (Java) interface of SpreadsheetBuilder looks like this:

public interface SpreadsheetBuilder {
  void build(@DelegatesTo(strategy = Closure.DELEGATE_FIRST, value = WorkbookDefinition.class) @ClosureParams(value = FromString.class, options = "builders.dsl.spreadsheet.builder.api.WorkbookDefinition") Configurer<WorkbookDefinition> workbookDefinition);
}

While debugging the execution of the code and the jar I found the difference while stepping through invokeMethod() of ClosureMetaClass.

When closure.getResolveStrategy(); in the working version is called Closure.DELEGATE_FIRST will be returned. Debugging the jar, the result will be 0 so that the MissingMethodException will be thrown later due to the wrong resolve strategy.

For now I have no idea how to solve this problem.

What is/could be the reason for this behavior? What can I do to solve this issue?

I'm using Grails 3.3.8 with Java OpenJDK 1.8.0_192.


Solution

  • If you don't need to support JDK 7, you could upgrade to Groovy Spreadsheet Builder 2.0.0.RC1 which is only JDK 8 compatible but appears to solve the problem.