JSR-303 ValueExtractor for Kotlin collections


#1

Hello,

We have a domain model represented by data classes which is validated by JSR-303 annotations. Unfortunately, I can’t get the Kotlin collections (List in particular) to be validated in the same fashion as the Java equivalents.
For Java lists JSR-303 provides out of the box ValueExtractor:

class ListValueExtractor implements ValueExtractor<List<@ExtractedValue ?>> {
static final ValueExtractorDescriptor DESCRIPTOR = new ValueExtractorDescriptor( new ListValueExtractor() );
private ListValueExtractor() {
}

@Override
public void extractValues(List<?> originalValue, ValueReceiver receiver) {
	for ( int i = 0; i < originalValue.size(); i++ ) {
		receiver.indexedValue( NodeImpl.LIST_ELEMENT_NODE_NAME, i, originalValue.get( i ) );
	}
}

}

Evidently, this extractor is not in play for Kotlin lists. Such that, the @NotBlank constraint on the list is never executed (the @NotNull on the plain String parameter works fine):

data class TestDto(val testList: List<@NotBlank String>, @NotNull val testVal: String)

Now, attempting to create a custom ValueExtractor for Kotlin lists does not compile at

class KotlinListValueExtractor : ValueExtractor<List<@ExtractedValue *>> { ...}

Here, the star-projection can not be annotated with @ExtractedValue the way Java does it <@ExtractedValue ?>. On the other hand, if I do ValueExtractor<List<@ExtractedValue Any?>> the @ExtractedValue annotation is completely lost at runtime and we get an exception when creating the ValueExtractorDescriptor:

 `javax.validation.valueextraction.ValueExtractorDefinitionException: HV000203: Value extractor type com.example.KotlinListValueExtractor fails to declare the extracted type parameter using @ExtractedValue.
at org.hibernate.validator.internal.engine.valueextraction.ValueExtractorDescriptor.getExtractedTypeParameter(ValueExtractorDescriptor.java:95)
at org.hibernate.validator.internal.engine.valueextraction.ValueExtractorDescriptor.<init>(ValueExtractorDescriptor.java:49)
at org.hibernate.validator.internal.engine.ConfigurationImpl.loadValueExtractorsFromServiceLoader(ConfigurationImpl.java:554)
at org.hibernate.validator.internal.engine.ConfigurationImpl.buildValidatorFactory(ConfigurationImpl.java:336)
at org.springframework.validation.beanvalidation.LocalValidatorFactoryBean.afterPropertiesSet(LocalValidatorFactoryBean.java:309)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1761)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1698)
... 72 more`  

Now I am wondering, if this is even the right path to take. Is there an alternative to enable value extraction in Kotlin? Need to mention also that the rest of the setup seems to be OK as Java domain classes (with Java Lists) within the same runtime work perfectly fine and get properly validated.

Thanks


#2

Hello, this looks like the same problem as https://youtrack.jetbrains.com/issue/KT-19289 (see also related issue https://youtrack.jetbrains.com/issue/KT-13228). If you feel like the problem is not completely covered by these issues please file a new one at http://kotl.in/issue. Thanks!