[ https://issues.apache.org/jira/browse/GROOVY-9183?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Paul King closed GROOVY-9183. ----------------------------- > 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)