You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "Paul King (JIRA)" <ji...@apache.org> on 2019/07/01 23:23:00 UTC
[jira] [Updated] (GROOVY-9183) Issue using @MapConstructor and
@NamedVarient
[ https://issues.apache.org/jira/browse/GROOVY-9183?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Paul King updated GROOVY-9183:
------------------------------
Description:
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.
was:
{{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:
{quote}CsvRowMapper.parse(*separator: '\t'*, tsvFileReader){quote}
{{I get an `GroovyCastException` because it's trying to set `headersRow` or `firstDataRow` to `null`:}}
{quote}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{quote}
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.
> Issue using @MapConstructor and @NamedVarient
> ---------------------------------------------
>
> 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
> Priority: Major
> Labels: named-parameters
> Attachments: MapConstructor.png, NamedVariant.png
>
>
> 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
(v7.6.3#76005)