Skip to content

Binding to a Map with EnumSet values fails with "Cannot create EnumSet for unknown element type" #15539

Closed
@olideakin

Description

@olideakin

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));?

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions