Description
When binding properties to type EnumSet, there is a failure with "Cannot create EnumSet for unknown element type" as the cause. Stack trace is as follows:
Caused by: java.lang.IllegalArgumentException: Cannot create EnumSet for unknown element type
at org.springframework.util.Assert.notNull(Assert.java:193)
at org.springframework.core.CollectionFactory.createCollection(CollectionFactory.java:195)
at org.springframework.core.CollectionFactory.createCollection(CollectionFactory.java:151)
at org.springframework.boot.context.properties.bind.CollectionBinder.lambda$bindAggregate$0(CollectionBinder.java:49)
at org.springframework.boot.context.properties.bind.AggregateBinder$AggregateSupplier.get(AggregateBinder.java:109)
at org.springframework.boot.context.properties.bind.IndexedElementsBinder.bindIndexed(IndexedElementsBinder.java:85)
at org.springframework.boot.context.properties.bind.IndexedElementsBinder.bindIndexed(IndexedElementsBinder.java:71)
at org.springframework.boot.context.properties.bind.CollectionBinder.bindAggregate(CollectionBinder.java:50)
at org.springframework.boot.context.properties.bind.AggregateBinder.bind(AggregateBinder.java:58)
at org.springframework.boot.context.properties.bind.Binder.lambda$bindAggregate$2(Binder.java:305)
at org.springframework.boot.context.properties.bind.Binder$Context.withIncreasedDepth(Binder.java:441)
at org.springframework.boot.context.properties.bind.Binder$Context.access$100(Binder.java:381)
at org.springframework.boot.context.properties.bind.Binder.bindAggregate(Binder.java:304)
at org.springframework.boot.context.properties.bind.Binder.bindObject(Binder.java:262)
at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:221)
... 57 common frames omitted
Debugging into the code, it appears this may be caused by a bug.
Stepping into CollectionBinder.bindAggregate(CollectionBinder.java), I can see that aggregateType is set to EnumSet and elementType is set to MyObject, which is expected. However the next lines are:
IndexedCollectionSupplier result = new IndexedCollectionSupplier(
() -> CollectionFactory.createCollection(collectionType, 0));
which does not pass in the elementType.
The next line (bindAggregate) is then invoked which eventually results in a call to the IndexedCollectionSupplier created above, which ends up in CollectionFactory.createCollection():
} else if (EnumSet.class == collectionType) {
Assert.notNull(elementType, "Cannot create EnumSet for unknown element type");
which of course does not have an elementType set because it was not passed into the earlier call, which then results in the assertion stack trace.
Perhaps the CollectionFactory.createCollection(collectionType, 0))
should actually be CollectionFactory.createCollection(collectionType, elementType, 0));
?