Conversion of Groovy Closure Type Parameters to Groovy Types
since 10.0 (Bees Knees)
There is a formula sandbox change to increase security: a new Advanced Configuration Option filterGroovyClosureParameterType enforces conversion of Groovy closure type parameters to their respective Groovy types. It is set to true
by default for newly created partitions on 10.0 servers.
Before 10.0
Types were not converted for Groovy Sandbox (such as DomainObject to Map) when used as a closure parameter.
In this example the cor
parameter is not a Map (as you may expect) but an instance of a DomainObject (in this particular case a CompensationRecord):
List cors = api.find("COR", 0, 1, null, null, Filter.equal("label", "SC_basic_logic"))?.collect()
cors.each {def cor ->
// work with "cor"
}
Note that if you explicitly set the type of cor
to Map, the code will fail with an error.
Since 10.0
After upgrade of existing partitions to 10.0, the conversion of types in closure parameters
is automatic just for LocalDateTime -> Date (which is safe in terms of backward compatibility).
other types will not be converted by default, because the conversion might break the existing Groovy code. Instead, there will be a specific warning in logs, i.e.:
PFUN-16195 groovy closure parameter type possible conversion: source type: net.pricefx.domain.CompensationRecord, target type: java.util.LinkedHashMap, groovy method: each
If you see this kind of log message, you should consider adding an Advanced Configuration Option filterGroovyClosureParameterType=true, which will:
enable automatic conversion for Groovy closure parameters to Map
will also remove the logging of the message
Then check your Groovy code for possible errors and fix them by using a proper data type, i.e. DomainObject will be converted to Map.
When filterGroovyClosureParameterType=true is not set (or is false), then:
this code:
cors.each {Map cor ->
will not workthis code:
cors.each {def cor ->
will workbecause
cor
is an instance of some DomainObject class.
When filterGroovyClosureParameterType=true is set, then:
both codes will work:
cors.each {Map cor ->
cors.each {def cor ->
but you will not be able to access the DomainObject, because it was converted to a Map.
Â
Found an issue in documentation? Write to us.
Â