Am working on migrating Groovy scripts from v4.3.2 to v5.0 to use Fluent API

Am rewriting a DynamicDataService from type GroovyDynamicDataService to type FluentDynamicDataService

I have the below snippet which parses a json using groovy.json.JsonSlurper

def slurper = new JsonSlurper()
def result = slurper.parseText('{"name":"Richard"}')
logger.info "result.name : " + result.name

While compiling, I get the below error,

Groovy Script saved with errors:

94: [Static type checking] - No such property: name for class: java.lang.Object
@ line 3, column 39.
logger.info "result.name : " + result.name

This works fine when I define the DynamicDataService of type GroovyDynamicDataService, but have issues with FluentDynamicDataService

The issue is in the way I try to access value using a key from the slurped object.

Can some one help me understand on how to refer the slurped json nodes when using FluentDynamicDataService?

    CommentAdd your comment...

    1 answer


      Great question.

      There are some fundamental differences in the Groovy execution environment between GroovyDynamicDataService and FluentDynamicDataService.

      Fluent services have a tighter security configuration and are statically compiled where legacy services are dynamically compiled. There are many advantages to this modified approach, for more info see the following links:

      In your code you are using dynamic type assignment by defining your variables to be of type 'def' and then accessing attributes of those variables (E.g. result.name). While you will get away with this in a dynamic compilation configuration, static type checking fails here because the compiler does not know the type of the 'result' object and therefore does not know that there is an attribute called 'name' on that object.

      With static type checking you need to be more explicit about the types of your variables and objects. This also has the added benefits of producing more intuitive and readable code, as well as activating IDE features like code complete when developing Groovy services in an IDE

      Now to resolve your issue you could just add the type declarations as shown below (noting that the JsonSlurper.parseText function actually returns a Map<String, Object>):

         JsonSlurper slurper = new JsonSlurper()
      Map<String, Object> result = (Map<String, Object>) slurper.parseText('{"name":"Richard"}')
      logger.info "result.name : " + result.name

      However, my recommendation would be that you review the Path utility class provided in the Fluent API (Path) which brings back some of the convenience of a dynamic environment and supports interrogation of JSON, XML, Map trees, and POJOs as described in this article:

      Using the Path utility your code could look like this:

         Path result = new Path('{"name":"Richard"}')
      logger.info "result.name : " + result.val('name')


      1. Sathiyachalam Baskar

        Ben, both the approaches are working here. Thank you for your suggestions.

      CommentAdd your comment...