[jira] [Resolved] (GROOVY-9183) Issue using @MapConstructor and @NamedVariant

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[jira] [Resolved] (GROOVY-9183) Issue using @MapConstructor and @NamedVariant

Paul King (Jira)

     [ https://issues.apache.org/jira/browse/GROOVY-9183?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Paul King resolved GROOVY-9183.
-------------------------------
    Fix Version/s: 3.0.0-rc-2
       Resolution: Fixed

Proposed PR applied. Thanks.

> Issue using @MapConstructor and @NamedVariant
> ---------------------------------------------
>
>                 Key: GROOVY-9183
>                 URL: https://issues.apache.org/jira/browse/GROOVY-9183
>             Project: Groovy
>          Issue Type: Bug
>          Components: groovy-runtime
>    Affects Versions: 2.5.7
>            Reporter: Eric Berry
>            Assignee: Eric Milles
>            Priority: Major
>              Labels: named-parameters
>             Fix For: 3.0.0-rc-2
>
>         Attachments: MapConstructor.png, NamedVariant.png
>
>          Time Spent: 40m
>  Remaining Estimate: 0h
>
> I have a static method marked with {{@NamedVariant}}, that takes a "Configuration" object as a parameter, which is marked with {{@NamedDelegate}}. The "Configuration" object is defined as a static inner class marked with {{@Immutable}}.
>  
> My Class:
> {quote}class CsvRowMapper \{
>     private final Settings settings
>     @NamedVariant
>     CsvRowMapper(Settings settings) \{
>         this.settings = settings
>     }
>     *@NamedVariant*
>     *static CsvRowMapper parse(@NamedDelegate Settings settings, Reader reader) {*
>         *new CsvRowMapper(settings).parse(reader)*
>     *}*
>     CsvRowMapper parse(Reader source) \{
>         // do work here
>         return this
>     }
>     *@Immutable*
>     *static class Settings {*
>         *String separator = ','*
>         *boolean headers = true*
>         *int headersRow = 0*
>         *int firstDataRow = 1*
>     *}*
> }{quote}
>  
> I've highlighted the important parts. The issue is when I use this class like:
> {code}
> CsvRowMapper.parse(*separator: '\t'*, tsvFileReader)
> {code}
>  
> I get an {{GroovyCastException}} because it's trying to set {{headersRow}} or {{firstDataRow}} to {{null}}:
>  
> {noformat}
> org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object '\{separator= , headers=null, headersRow=null, firstDataRow=null}'
>   with class 'java.util.LinkedHashMap' to class 'CsvRowMapper$Settings'
>   due to: org.codehaus.groovy.runtime.typehandling.GroovyCastException:
>     Cannot cast object 'null' with class 'null' to class 'int'. Try 'java.lang.Integer' instead
> {noformat}
>  
> Even though there are default values for each setting.
>  
> I loaded up this into GroovyConsole, and I think the issue is that the {{@NameVariant}} version of the `parse` method is creating a map with ALL keys for the {{@NamedDelegate}} {{Settings}} class (See NamedVariant.png).
>  
> Furthermore the {{@Immutable}} annotation adds {{@MapConstructor}} to my {{Settings}} class, which only checks if the given map contains the *`key`*, not also if it has a `value` (See MapConstructor.png).
>  
> The {{@NamedVariant}} passes a map containing null values for all keys not supplied during method execution, and {{@MapConstructor}} only checks if the given map has the key, not a value.
>  



--
This message was sent by Atlassian Jira
(v8.3.4#803005)