[hibernate-issues] [JIRA] (HV-1796) Kotlin extension function on parameterized type leads to ArrayIndexOutOfBoundsException during validateParameters

Frédéric Chuong (JIRA) jira at hibernate.atlassian.net
Tue Aug 4 12:41:08 EDT 2020


Frédéric Chuong ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%3A4ca290af-dd15-4cd2-ba2d-7a48f3908c1f ) *created* an issue

Hibernate Validator ( https://hibernate.atlassian.net/browse/HV?atlOrigin=eyJpIjoiZTNhYTY2OWYxNjAwNDVhNGE1ZDZkOWI3YjgxZjI3MWQiLCJwIjoiaiJ9 ) / Bug ( https://hibernate.atlassian.net/browse/HV-1796?atlOrigin=eyJpIjoiZTNhYTY2OWYxNjAwNDVhNGE1ZDZkOWI3YjgxZjI3MWQiLCJwIjoiaiJ9 ) HV-1796 ( https://hibernate.atlassian.net/browse/HV-1796?atlOrigin=eyJpIjoiZTNhYTY2OWYxNjAwNDVhNGE1ZDZkOWI3YjgxZjI3MWQiLCJwIjoiaiJ9 ) Kotlin extension function on parameterized type leads to ArrayIndexOutOfBoundsException during validateParameters ( https://hibernate.atlassian.net/browse/HV-1796?atlOrigin=eyJpIjoiZTNhYTY2OWYxNjAwNDVhNGE1ZDZkOWI3YjgxZjI3MWQiLCJwIjoiaiJ9 )

Issue Type: Bug Affects Versions: 6.0.18.Final, 6.1.5.Final Assignee: Unassigned Attachments: image-2020-08-05-00-24-18-321.png Components: engine Created: 04/Aug/2020 09:41 AM Environment: Hibernate Validator 6.1.5.Final
zulu11.35.15-ca-jdk11.0.5-win_x64 (observed against IBM Java 8 too)
Kotlin 1.3.72
Gradle 6.5.1
Windows 10 Priority: Minor Reporter: Frédéric Chuong ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%3A4ca290af-dd15-4cd2-ba2d-7a48f3908c1f )

*******
Context
*******

* Method constraints validation
* Kotlin

* Presence of extension function on parameterized type within the validated object

*******
Problem
*******

Given the following code making use of method constraint validation

*SimpleFooService.kt*
package foo

import org.slf4j.LoggerFactory
import javax.validation.Validation
import javax.validation.constraints.NotEmpty

class SimpleFooService {
   fun methodName(@NotEmpty ignored: String ) {
       // no-op
   }

   private fun List< String >.someExtensionFunction(extensionFunctionArg: Int) = Unit
}

fun main() {
   val validator = Validation.buildDefaultValidatorFactory().validator
   val executableValidator = validator.forExecutables()
   try {
       executableValidator.validateParameters(
           SimpleFooService(),
           SimpleFooService:: class. java.getDeclaredMethod(SimpleFooService::methodName.name, String :: class. java),
           arrayOf( "Some value" )
       )
   } catch (e: Exception) {
       log.error( "Error" , e)
   }
}

val log = LoggerFactory.getLogger(SimpleFooService:: class. java)

Attempting to execute the code leads to ArrayIndexOutOfBoundsException and the given arguments not being validated:

2020-08-04 16:14:41,937 [main] DEBUG - org.jboss.logging - Logging Provider: org.jboss.logging.Slf4jLoggerProvider
2020-08-04 16:14:41,949 [main]  INFO - org.hibernate.validator.internal.util.Version - HV000001: Hibernate Validator 6.1.5.Final
2020-08-04 16:14:41,975 [main] DEBUG - org.hibernate.validator.internal.xml.config.ValidationXmlParser - Trying to load META-INF/validation.xml for XML based Validator configuration.
2020-08-04 16:14:41,977 [main] DEBUG - org.hibernate.validator.internal.xml.config.ResourceLoaderHelper - Trying to load META-INF/validation.xml via TCCL
2020-08-04 16:14:41,979 [main] DEBUG - org.hibernate.validator.internal.xml.config.ResourceLoaderHelper - Trying to load META-INF/validation.xml via Hibernate Validator's class loader
2020-08-04 16:14:41,980 [main] DEBUG - org.hibernate.validator.internal.xml.config.ValidationXmlParser - No META-INF/validation.xml found. Using annotation based configuration only.
2020-08-04 16:14:41,986 [main] DEBUG - org.hibernate.validator.internal.engine.resolver.TraversableResolvers - Cannot find javax.persistence.Persistence on classpath. Assuming non JPA 2 environment. All properties will per default be traversable.
2020-08-04 16:14:42,083 [main] DEBUG - org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator - Loaded expression factory via original TCCL
2020-08-04 16:14:42,434 [main] DEBUG - org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper - HV000252: Using org.hibernate.validator.internal.engine.DefaultPropertyNodeNameProvider as property node name provider.
2020-08-04 16:14:42,443 [main] DEBUG - org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper - HV000234: Using org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator as ValidatorFactory-scoped message interpolator.
2020-08-04 16:14:42,443 [main] DEBUG - org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper - HV000234: Using org.hibernate.validator.internal.engine.resolver.TraverseAllTraversableResolver as ValidatorFactory-scoped traversable resolver.
2020-08-04 16:14:42,443 [main] DEBUG - org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper - HV000234: Using org.hibernate.validator.internal.util.ExecutableParameterNameProvider as ValidatorFactory-scoped parameter name provider.
2020-08-04 16:14:42,444 [main] DEBUG - org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper - HV000234: Using org.hibernate.validator.internal.engine.DefaultClockProvider as ValidatorFactory-scoped clock provider.
2020-08-04 16:14:42,444 [main] DEBUG - org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper - HV000234: Using org.hibernate.validator.internal.engine.scripting.DefaultScriptEvaluatorFactory as ValidatorFactory-scoped script evaluator factory.
2020-08-04 16:14:42,541 [main] ERROR - foo.SimpleFooService - Error
java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
	at org.hibernate.validator.internal.metadata.provider.AnnotationMetaDataProvider.getTypeParametersCascadingMetaDataForParameterizedType(AnnotationMetaDataProvider.java:678) ~[hibernate-validator-6.1.5.Final.jar:6.1.5.Final]
	at org.hibernate.validator.internal.metadata.provider.AnnotationMetaDataProvider.getTypeParametersCascadingMetadata(AnnotationMetaDataProvider.java:660) ~[hibernate-validator-6.1.5.Final.jar:6.1.5.Final]
	at org.hibernate.validator.internal.metadata.provider.AnnotationMetaDataProvider.findCascadingMetaData(AnnotationMetaDataProvider.java:627) ~[hibernate-validator-6.1.5.Final.jar:6.1.5.Final]
	at org.hibernate.validator.internal.metadata.provider.AnnotationMetaDataProvider.getParameterMetaData(AnnotationMetaDataProvider.java:432) ~[hibernate-validator-6.1.5.Final.jar:6.1.5.Final]
	at org.hibernate.validator.internal.metadata.provider.AnnotationMetaDataProvider.findExecutableMetaData(AnnotationMetaDataProvider.java:308) ~[hibernate-validator-6.1.5.Final.jar:6.1.5.Final]
	at org.hibernate.validator.internal.metadata.provider.AnnotationMetaDataProvider.getMetaData(AnnotationMetaDataProvider.java:292) ~[hibernate-validator-6.1.5.Final.jar:6.1.5.Final]
	at org.hibernate.validator.internal.metadata.provider.AnnotationMetaDataProvider.getMethodMetaData(AnnotationMetaDataProvider.java:279) ~[hibernate-validator-6.1.5.Final.jar:6.1.5.Final]
	at org.hibernate.validator.internal.metadata.provider.AnnotationMetaDataProvider.retrieveBeanConfiguration(AnnotationMetaDataProvider.java:130) ~[hibernate-validator-6.1.5.Final.jar:6.1.5.Final]
	at org.hibernate.validator.internal.metadata.provider.AnnotationMetaDataProvider.getBeanConfiguration(AnnotationMetaDataProvider.java:120) ~[hibernate-validator-6.1.5.Final.jar:6.1.5.Final]
	at org.hibernate.validator.internal.metadata.BeanMetaDataManagerImpl.getBeanConfigurationForHierarchy(BeanMetaDataManagerImpl.java:234) ~[hibernate-validator-6.1.5.Final.jar:6.1.5.Final]
	at org.hibernate.validator.internal.metadata.BeanMetaDataManagerImpl.createBeanMetaData(BeanMetaDataManagerImpl.java:201) ~[hibernate-validator-6.1.5.Final.jar:6.1.5.Final]
	at org.hibernate.validator.internal.metadata.BeanMetaDataManagerImpl.getBeanMetaData(BeanMetaDataManagerImpl.java:165) ~[hibernate-validator-6.1.5.Final.jar:6.1.5.Final]
	at org.hibernate.validator.internal.engine.ValidatorImpl.validateParameters(ValidatorImpl.java:267) ~[hibernate-validator-6.1.5.Final.jar:6.1.5.Final]
	at org.hibernate.validator.internal.engine.ValidatorImpl.validateParameters(ValidatorImpl.java:235) ~[hibernate-validator-6.1.5.Final.jar:6.1.5.Final]
	at foo.FooServiceKt.main(FooService.kt:19) ~[main/:na]
	at foo.FooServiceKt.main(FooService.kt) ~[main/:na]

********************
Preliminary analysis
********************

Debugging reveals that org.hibernate.validator.internal.metadata.provider.AnnotationMetaDataProvider#findExecutableMetaData ( https://github.com/hibernate/hibernate-validator/blob/6.1.5.Final/engine/src/main/java/org/hibernate/validator/internal/metadata/provider/AnnotationMetaDataProvider.java#L307 ) is retrieving a incorrect JavaBeanExecutable result from JavaBeanHelper when processing the private final void foo.SimpleFooService.someExtensionFunction(java.util.List,int) method:

( https://hibernate.atlassian.net/secure/attachment/49727/49727_image-2020-08-05-00-24-18-321.png )

The extensionFunctionArg argument has the List<String> type associated to it, instead of int

That inconsistency causes AnnotationMetaDataProvider.getTypeParametersCascadingMetaDataForParameterizedType to fail.

**********
Workaround
**********

Workaround is to remove all extension functions on parameterized receiver from the validated class (which may not be desirable).

***********
Build setup
***********

*build.gradle.kts*
import org.jetbrains.kotlin.gradle.dsl.KotlinCompile
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions

plugins {
   kotlin( "jvm" ) version "1.3.72"
}

group = "org.example"
version = "1.0-SNAPSHOT"

repositories {
   mavenCentral()
}

dependencies {
   implementation(kotlin( "stdlib" ))
   implementation(platform( "org.springframework.boot:spring-boot-dependencies:2.3.2.RELEASE" ))
   implementation( "org.slf4j:slf4j-api" )
   implementation( "ch.qos.logback:logback-classic" )
   implementation( "org.hibernate.validator:hibernate-validator" )
   implementation( "org.glassfish:jakarta.el" )
}

tasks {
   "wrapper" (Wrapper::class) {
       gradleVersion = "6.5.1"
       distributionType = Wrapper.DistributionType.ALL
   }
   withType<KotlinCompile<KotlinJvmOptions>>().configureEach {
       kotlinOptions {
           jvmTarget = "11"
           javaParameters = true
       }
   }
}

( https://hibernate.atlassian.net/browse/HV-1796#add-comment?atlOrigin=eyJpIjoiZTNhYTY2OWYxNjAwNDVhNGE1ZDZkOWI3YjgxZjI3MWQiLCJwIjoiaiJ9 ) Add Comment ( https://hibernate.atlassian.net/browse/HV-1796#add-comment?atlOrigin=eyJpIjoiZTNhYTY2OWYxNjAwNDVhNGE1ZDZkOWI3YjgxZjI3MWQiLCJwIjoiaiJ9 )

Get Jira notifications on your phone! Download the Jira Cloud app for Android ( https://play.google.com/store/apps/details?id=com.atlassian.android.jira.core&referrer=utm_source%3DNotificationLink%26utm_medium%3DEmail ) or iOS ( https://itunes.apple.com/app/apple-store/id1006972087?pt=696495&ct=EmailNotificationLink&mt=8 ) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100141- sha1:8f92423 )
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/hibernate-issues/attachments/20200804/df2ea554/attachment.html 


More information about the hibernate-issues mailing list