Query on the Secondary Index throwing Error: InaccessibleObjectException

We have a Table with Id as primary key. Now, we are trying to add Secondary Index to one column called “userId” and did so by using @Indexed. Even added findByUserId in its repository. But, While Querying with findByUserId is throwing this error.

Cause:
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 @2ba867a6

System: Java 17, springboot 3.1.1, spring-boot-starter-data-aerospike:0.12.0

Just a Update: On further deep-dive, found that it was actually able to query on secondary Index but while converting from Bin values to Java Object was failing. Due to the above error.

Hi Kailash,

Thanks for raising this. The issue is caused by changes in Java 9 to security handling of classes using reflection (such as Spring Data). The correct solution appears to be adding/changing the custom converters we have for some of the Numeric subclasses, but this is a longer term solution. We are working on this and hope to have it out in the next release of Spring Data (4.6) but it’s early in the investigation of the solution so we cannot guarantee this at this stage.

In the meantime, there is a workaround to allow you to proceed. You can pass

--add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.math=ALL-UNNAMED

on the command line to allow this reflection code to pass the security checks on the java.util and java.math packages. So my application command line looks like:

java --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.math=ALL-UNNAMED -jar SpringDataExample-0.0.1-SNAPSHOT.jar

If you want to run tests within an IDE, you can add

	<build>
		<plugins>
			...
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-surefire-plugin</artifactId>
				<configuration>
					<argLine>--add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.math=ALL-UNNAMED</argLine>
				</configuration>
			</plugin>
		</plugins>
	</build>

to your pom.xml file to allow them to pass. This will only help with unit tests. though.

Please let me know if this works around your problem or not for now.

If it doesn’t, it’s pretty easy to add in a custom converter. Aerospike’s Spring Data v4.5 there is a BigDecimal converter, but not a BigInteger one. It’s moderately easy to add a BigInteger one, the code would be something similar to:

public class AerospikeConfiguration extends AbstractAerospikeDataConfiguration {
...

    // Optional. Only needed when you need custom converters
    @Override
    protected List<?> customConverters() {
        return List.of(
                BigIntegerConverter.BigIntegerToStringConverter.INSTANCE,
                BigIntegerConverter.StringToBigIntegerConverter.INSTANCE
        );
    }

    @Value
    static
    class BigIntegerConverter {
        @WritingConverter
        public enum BigIntegerToStringConverter implements Converter<BigInteger, String> {
            INSTANCE;

            @Override
            public String convert(BigInteger source) {
                return source.toString();
            }
        }

        @ReadingConverter
        public enum StringToBigIntegerConverter implements Converter<String, BigInteger> {
            INSTANCE;

            @Override
            public BigInteger convert(String source) {
                return new BigInteger(source);
            }
        }
    }