Skip to content

Issue with Parameter of type array with generics wildcard vs raw type #415

Closed
@NicoKiaru

Description

@NicoKiaru

Hi,

I noticed a strange behaviour with scijava parameters. It looks like the handling of array parameters are very different if they contain a generics wildcard or not:

Let's imagine a class:

public class MyClass<T> {

}

And a scijava converter from String to MyClass<?>[] (not sure the wildcard changes anything if present in the converter)

This:

@Parameter
MyClass[] myobjects;

behaves correctly with regards to the scijava mechanism. The correct converter is called.

However this:

@Parameter
MyClass<?>[] myobjects;

completely fails : in the test case I have, the scijava mechanism attempts to put a File[] object into myobjects, obviously failing.

I narrowed down the issue to the CommandModuleItem class. The line

final Class<?> type = Types.raw(Types.fieldType(field, getDelegateClass()));
returns the type of the parameter. In case the Parameter has no generics wildcard, then the returned type is [L MyClass, while if it has a generics widlcard, this same line returns [L Object, wrongfully allowing irrelevant converters (thus the one from String to File array).

I have not made a minimal example of this issue, but one test in bigdataviewer-playground can be used to reproduce the issue : https://github.com/bigdataviewer/bigdataviewer-playground/blob/fixes-rawtype/src/test/src/sc/fiji/bdvpg/scijava/ScijavaShowDemo.java.

The demo fails. But if you remove the wildcard in the line https://github.com/bigdataviewer/bigdataviewer-playground/blob/daab0a336831b89c44d13932c243dd41e493dbe5/src/main/java/sc/fiji/bdvpg/scijava/command/bdv/BdvSourcesAdderCommand.java#L49:

SourceAndConverter[] sacs;

Then everything works.

How can this be solved ? I'm also open to suggestions on my code. I tend to fear that modifying scijava common is risky. So if there's a solution on bigdataviewer-playground side I would rather do it. I can think of 3 options:

  • keeping raws type in the parameters : this creates annoying issues when converting to List + we are not supposed to use raw types in Java as far as I understood
  • making a container class : SourceAndConverterList which would hold a single field List<SourceAndConverter>. This seems the most easy thing to do a provides a lot of control on the scijava side - but it's a bit inelegant
  • managing to make a working List<SourceAndConverter<?>> scijava parameter, but I have no idea if this is possible. To me, because the generic types are erased at runtime, this looks impossible, but is it really ?

Here's some maybe related issues:

#172

#118

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions