question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Java 17: InaccessibleObjectException due to illegal reflective access when saving entities containing a BigDecimal

See original GitHub issue

I’m currently trying to migrate a project from Java 11 to Java 17 and I’m not able to get any code running when saving an entity containing a BigDecimal object in ElasticSearch. When trying to do so, I run into the following exception:

java.lang.reflect.InaccessibleObjectException: Unable to make field private final java.math.BigInteger java.math.BigDecimal.intVal accessible: module java.base does not "opens java.math" to unnamed module @2758fe70
	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:787)
	at org.springframework.data.mapping.context.AbstractMappingContext$PersistentPropertyCreator.doWith(AbstractMappingContext.java:520)
	at org.springframework.util.ReflectionUtils.doWithFields(ReflectionUtils.java:710)
	at org.springframework.data.mapping.context.AbstractMappingContext.doAddPersistentEntity(AbstractMappingContext.java:401)
	at org.springframework.data.mapping.context.AbstractMappingContext.addPersistentEntity(AbstractMappingContext.java:365)
	at java.base/java.util.Collections$SingletonSet.forEach(Collections.java:4905)
	at org.springframework.data.mapping.context.AbstractMappingContext$PersistentPropertyCreator.createAndRegisterProperty(AbstractMappingContext.java:568)
	at org.springframework.data.mapping.context.AbstractMappingContext$PersistentPropertyCreator.doWith(AbstractMappingContext.java:526)
	at org.springframework.util.ReflectionUtils.doWithFields(ReflectionUtils.java:710)
	at org.springframework.data.mapping.context.AbstractMappingContext.doAddPersistentEntity(AbstractMappingContext.java:401)
	at org.springframework.data.mapping.context.AbstractMappingContext.addPersistentEntity(AbstractMappingContext.java:365)
	at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:258)
	at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:201)
	at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:87)
	at org.springframework.data.mapping.context.MappingContext.getRequiredPersistentEntity(MappingContext.java:73)
	at org.springframework.data.elasticsearch.core.AbstractElasticsearchTemplate.getRequiredPersistentEntity(AbstractElasticsearchTemplate.java:646)
	at org.springframework.data.elasticsearch.core.AbstractElasticsearchTemplate.getIndexCoordinatesFor(AbstractElasticsearchTemplate.java:583)
	at org.springframework.data.elasticsearch.core.AbstractElasticsearchTemplate.save(AbstractElasticsearchTemplate.java:180)
	at com.redacted.ComponentTest.saveBigDecimal(ComponentTest.java:84)

I created two tests to check where the problem may lie. The Integer test succeeds, yet the BigDecimal test fails with the above exception.

@Test
  public void saveBigDecimal() {
    elasticsearchRestTemplate.save(new BigDecimalWrapper());
  }

  @Test
  public void saveInteger() {
    elasticsearchRestTemplate.save(new IntegerWrapper());
  }

  @Document(indexName = "bigDecimal-wrapper")
  static class BigDecimalWrapper{
    BigDecimal one = BigDecimal.ONE;
    BigDecimal ten = BigDecimal.TEN;
    String someString = "yeah";
  }

  @Document(indexName = "integer-wrapper")
  static class IntegerWrapper{
    Integer one = 1;
    int ten = 10;
    String someString = "yeah";
  }

image

To run this I am using Java 17 with SpringBoot 2.5.8 containing Spring Data ElasticSearch 4.2.7. I’m happy to provide more details if necessary, please let me know.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:10

github_iconTop GitHub Comments

1reaction
sothawocommented, Jan 2, 2022

You need to derive your configuration class from AbstractElasticsearchConfiguration like it’s shown in the documentation.

This not only creates the client but also initializes the internal objects like ElasticsearchMapper or the registered conversions. Spring Data Elasticsearch has some internal conversions built in, one is for converting BigDecimal to Double and back. (Elasticsearch does not support BigDecimal types, see https://www.elastic.co/guide/en/elasticsearch/reference/7.16/number.html).

So your configuration class would be (the second bean you had is provided by the base class already):

@Configuration
@EnableElasticsearchRepositories(basePackages = ["com.example"])
class ElasticsearchConfig(private val elasticsearchProperties: ElasticsearchProperties) : AbstractElasticsearchConfiguration() {
	@Bean
	override fun elasticsearchClient(): RestHighLevelClient {

		val clientConfiguration: ClientConfiguration = ClientConfiguration.builder()
			.connectedTo(elasticsearchProperties.url)
			.withBasicAuth(elasticsearchProperties.username, elasticsearchProperties.password)
			.build()
		return RestClients.create(clientConfiguration)
			.rest()
	}
}

Besides that, I’d recommend to add @Field annotations to your entity, so that when the application starts and the index is created, a correct mapping is written to the index; otherwise the type to use will be subject to Elasticsearch autodetection:

@Document(indexName = "testmodel")
data class TestModel(

	@Id
	val id: String,

	@Field(type = FieldType.Text)
	val test: String,

	@Field(type = FieldType.Double)
	val testValue: BigDecimal,
)
0reactions
ameltonyancommented, Feb 28, 2022

I have the same problem and extending from AbstractElasticsearchConfiguration class solves the problem. Thanks a lot.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Java 9 Illegal Reflective Access Warning - Baeldung
When using reflection to access a named module from another named module, we'll get an IllegalAccessException or InaccessibleObjectException.
Read more >
module {A} does not 'opens {package}' to {B}") on Java 9 ...
A library or framework uses reflection to call into a JDK module. ... But the solution with --illegal-access will stop working from JDK...
Read more >
Deprecated List (Java SE 10 & JDK 10 ) - Oracle Help Center
This class is deprecated and subject to removal in a future version of Java SE. It has been replaced by java.security.Policy and related...
Read more >
Apache Tomcat 9 (9.0.70) - Changelog
Add support for specifying Java 17 (with the value 17 ) as the compiler ... Regression when generating reflection due to removed NIO...
Read more >
Bug List - Bugs - Eclipse
ID Product Comp△ Assignee▽ Status▽ Resolution Changed▽ 580591 4DIAC 4DIAC‑ID 4diac‑inbox CLOS FIXE Sun 15:43 580472 4DIAC 4DIAC‑ID 4diac‑inbox CLOS FIXE Sun 15:43 579953 4DIAC FORTE...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found