-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Expected Behavior
When creating a bean that has @Parameter SequencedSet<Integer> set in its constructor argument list, I expect passing a LinkedHashSet to createBean to create a new instance of that bean.
Actual Behaviour
The bean context throws an exception that it can't convert the object to a SequencedSet:
io.micronaut.context.exceptions.BeanInstantiationException: Error instantiating bean of type [com.example.Application$A]
Message: Invalid bean @Argument [SequencedSet<Integer E> set]. Cannot convert object [[]] to required type: interface java.util.SequencedSet
Path Taken:
new c.e.A$A([@Parameter SequencedSet<Integer> set])
at io.micronaut.context.DefaultBeanContext.lambda$resolveArgumentValues$15(DefaultBeanContext.java:1117)
at java.base/java.util.Optional.orElseThrow(Optional.java:403)
at io.micronaut.context.DefaultBeanContext.resolveArgumentValues(DefaultBeanContext.java:1116)
at io.micronaut.context.DefaultBeanContext.doCreateBeanWithArguments(DefaultBeanContext.java:1080)
at io.micronaut.context.DefaultBeanContext.createBean(DefaultBeanContext.java:1063)
at io.micronaut.context.BeanContext.createBean(BeanContext.java:157)
at com.example.Application.run(Application.java:26)
at picocli.CommandLine.executeUserObject(CommandLine.java:2045)
at picocli.CommandLine.access$1500(CommandLine.java:148)
at picocli.CommandLine$RunLast.executeUserObjectOfLastSubcommandWithSameParent(CommandLine.java:2469)
at picocli.CommandLine$RunLast.handle(CommandLine.java:2461)
at picocli.CommandLine$RunLast.handle(CommandLine.java:2423)
at picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:2277)
at picocli.CommandLine$RunLast.execute(CommandLine.java:2425)
at picocli.CommandLine.execute(CommandLine.java:2174)
at io.micronaut.configuration.picocli.PicocliRunner.run(PicocliRunner.java:146)
at io.micronaut.configuration.picocli.PicocliRunner.run(PicocliRunner.java:123)
at com.example.Application.main(Application.java:19)
Steps To Reproduce
- Create a bean class with a
SequencedSetparameter:
@Bean
static class A {
public A(@Parameter SequencedSet<Integer> set) {
System.out.println(set.getClass());
}
}Note that with SequencedSet<Object> as the argument type, this works fine.
- Call
BeanContext#createBeanwith aLinkedHashSet:
context.createBean(A.class, new LinkedHashSet<>());I attached a debugger and apparently both the DefaultBeanContext and DefaultMutableConversionService insist on doing conversion if the object matches the target type but is a Map or Iterable.
Tangentially, if the parameter in A above was changed to Set, the bean creation works, but the constructor would get a HashSet as its argument instead of the originally passed LinkedHashSet (with the same elements though). The same thing happens seemingly for all other Iterable and Map types: the values in the map or iterable are repackaged in a new instance of potentially different type.
Not sure what the contract here actually is, but intuitively, I would have expected reference equality between the argument passed to createBean and the argument passed to the bean constructor (if they're compatible to the argument type)
Environment Information
- JDK Version: OpenJDK 21.0.2. OpenJDK 25.0.1
- Ubuntu 24.04
Example Application
No response
Version
4.10.2, 4.10.3-SNAPSHOT, 5.0.0-SNAPSHOT
Metadata
Metadata
Assignees
Labels
Type
Projects
Status