tarantool / cartridge-springdata

Spring Data Tarantool

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

JRE17 support: passing collection parameters into stored procedue fails

savinov opened this issue · comments

cartridge-springdata cannot be run with JRE17 because of strong internals encapsulation policy: https://openjdk.java.net/jeps/403

The problem is cartridge-springdata's TarantoolTemplate map parameters: https://github.com/tarantool/cartridge-springdata/blob/v0.5.3/src/main/java/org/springframework/data/tarantool/core/BaseTarantoolTemplate.java#L387

That mapping uses converter: https://github.com/tarantool/cartridge-springdata/blob/v0.5.3/src/main/java/org/springframework/data/tarantool/core/convert/MappingTarantoolWriteConverter.java#L103

The converter tries to get persisted entity from spring-data-common's AbstractMappingContext: https://github.com/spring-projects/spring-data-commons/blob/2.7.18/src/main/java/org/springframework/data/mapping/context/AbstractMappingContext.java#L575

AbstractMappingContext uses reflection to make fields accessable, but JRE17 restricts modifications on non-public API's.

Calling tarantool stored procedure from repository leads to InaccessibleObjectException.

Demo project with spring-data-tarantool 0.5.3 and spring-boot 2.7.18: https://github.com/savinov/cartridge-springdata-jdk17/tree/issue139

Run RepositoryTest

Result:

java.lang.reflect.InaccessibleObjectException: Unable to make field private final java.lang.Object java.util.ImmutableCollections$List12.e0 accessible: module java.base does not "opens java.util" to unnamed module @1e88b3c

	at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
	at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
	at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:178)
	at java.base/java.lang.reflect.Field.setAccessible(Field.java:172)
	at org.springframework.util.ReflectionUtils.makeAccessible(ReflectionUtils.java:783)
	at org.springframework.data.mapping.context.AbstractMappingContext$PersistentPropertyCreator.doWith(AbstractMappingContext.java:575)
	at org.springframework.util.ReflectionUtils.doWithFields(ReflectionUtils.java:706)
	at org.springframework.data.mapping.context.AbstractMappingContext.doAddPersistentEntity(AbstractMappingContext.java:449)
	at org.springframework.data.mapping.context.AbstractMappingContext.addPersistentEntity(AbstractMappingContext.java:406)
	at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:291)
	at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:209)
	at org.springframework.data.tarantool.core.convert.MappingTarantoolWriteConverter.write(MappingTarantoolWriteConverter.java:103)
	at org.springframework.data.tarantool.core.convert.MappingTarantoolWriteConverter.write(MappingTarantoolWriteConverter.java:67)
	at org.springframework.data.tarantool.core.convert.MappingTarantoolConverter.write(MappingTarantoolConverter.java:78)
	at org.springframework.data.tarantool.core.BaseTarantoolTemplate.mapParameters(BaseTarantoolTemplate.java:387)

Similar issue in spring-data-mongodb: spring-projects/spring-data-mongodb#3980

The problem is spring-data-commons apply reflection to List parameter passed into repository stored procedure function.
There is workaround: replace List parameter with array: savinov/cartridge-springdata-jdk17@5e277eb