Native Image Hazelcast error: java.lang.NoSuchMethodError: com.hazelcast.map.IMap.getName() (original) (raw)

Describe the bug

I've run into the same situation as reported here:
https://stackoverflow.com/questions/76807745/hazelcast-with-spring-boot-3-graalvm-native-nosuchmethoderror

Basically, both Hazelcast and Spring Boot are working with Native Image, but sadly Micrometer's HazelcastCacheMetrics breaks this compatibility with: java.lang.NoSuchMethodError: com.hazelcast.map.IMap.getName()

There is no workaround available, sadly.

Extended stacktrace:

Caused by: java.lang.ExceptionInInitializerError
    at io.micrometer.core.instrument.binder.cache.HazelcastCacheMetrics.<init>(HazelcastCacheMetrics.java:79)
    at org.springframework.boot.actuate.metrics.cache.HazelcastCacheMeterBinderProvider.getMeterBinder(HazelcastCacheMeterBinderProvider.java:47)
    at org.springframework.boot.actuate.metrics.cache.HazelcastCacheMeterBinderProvider.getMeterBinder(HazelcastCacheMeterBinderProvider.java:41)
    at org.springframework.boot.actuate.metrics.cache.CacheMetricsRegistrar.lambda$getMeterBinder$0(CacheMetricsRegistrar.java:76)
    at org.springframework.boot.util.LambdaSafe$Callbacks.lambda$invokeAnd$2(LambdaSafe.java:301)
    at org.springframework.boot.util.LambdaSafe$LambdaSafeCallback.invoke(LambdaSafe.java:159)
    at org.springframework.boot.util.LambdaSafe$Callbacks.lambda$invokeAnd$3(LambdaSafe.java:300)
    at java.base@17.0.9/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
    at java.base@17.0.9/java.util.Spliterators$IteratorSpliterator.tryAdvance(Spliterators.java:1856)
    at java.base@17.0.9/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:129)
    at java.base@17.0.9/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:527)
    at java.base@17.0.9/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513)
    at java.base@17.0.9/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
    at java.base@17.0.9/java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:150)
    at java.base@17.0.9/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.base@17.0.9/java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:647)
    at org.springframework.boot.actuate.metrics.cache.CacheMetricsRegistrar.getMeterBinder(CacheMetricsRegistrar.java:78)
    at org.springframework.boot.actuate.metrics.cache.CacheMetricsRegistrar.bindCacheToRegistry(CacheMetricsRegistrar.java:63)
    at org.springframework.boot.actuate.autoconfigure.metrics.cache.CacheMetricsRegistrarConfiguration.bindCacheToRegistry(CacheMetricsRegistrarConfiguration.java:76)
    at org.springframework.boot.actuate.autoconfigure.metrics.cache.CacheMetricsRegistrarConfiguration.lambda$bindCacheManagerToRegistry$0(CacheMetricsRegistrarConfiguration.java:71)
    at java.base@17.0.9/java.lang.Iterable.forEach(Iterable.java:75)
    at org.springframework.boot.actuate.autoconfigure.metrics.cache.CacheMetricsRegistrarConfiguration.bindCacheManagerToRegistry(CacheMetricsRegistrarConfiguration.java:71)
    at java.base@17.0.9/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721)
    at org.springframework.boot.actuate.autoconfigure.metrics.cache.CacheMetricsRegistrarConfiguration.bindCachesToRegistry(CacheMetricsRegistrarConfiguration.java:66)
    at org.springframework.boot.actuate.autoconfigure.metrics.cache.CacheMetricsRegistrarConfiguration.<init>(CacheMetricsRegistrarConfiguration.java:57)
    at org.springframework.boot.actuate.autoconfigure.metrics.cache.CacheMetricsRegistrarConfiguration__BeanDefinitions.lambda$getCacheMetricsRegistrarConfigurationInstanceSupplier$0(CacheMetricsRegistrarConfiguration__BeanDefinitions.java:23)
    at org.springframework.util.function.ThrowingBiFunction.apply(ThrowingBiFunction.java:68)
    at org.springframework.util.function.ThrowingBiFunction.apply(ThrowingBiFunction.java:54)
    at org.springframework.beans.factory.aot.BeanInstanceSupplier.lambda$get$2(BeanInstanceSupplier.java:206)
    at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:58)
    at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:46)
    at org.springframework.beans.factory.aot.BeanInstanceSupplier.invokeBeanSupplier(BeanInstanceSupplier.java:214)
    at org.springframework.beans.factory.aot.BeanInstanceSupplier.get(BeanInstanceSupplier.java:206)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.obtainInstanceFromSupplier(DefaultListableBeanFactory.java:949)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainFromSupplier(AbstractAutowireCapableBeanFactory.java:1237)
    ... 17 more
Caused by: java.lang.IllegalStateException: java.lang.NoSuchMethodException: no such method: com.hazelcast.map.IMap.getName()String/invokeInterface
    at io.micrometer.core.instrument.binder.cache.HazelcastIMapAdapter.resolveIMapMethod(HazelcastIMapAdapter.java:260)
    at io.micrometer.core.instrument.binder.cache.HazelcastIMapAdapter.<clinit>(HazelcastIMapAdapter.java:53)
    ... 52 more
Caused by: java.lang.NoSuchMethodException: no such method: com.hazelcast.map.IMap.getName()String/invokeInterface
    at java.base@17.0.9/java.lang.invoke.MemberName.makeAccessException(MemberName.java:976)
    at java.base@17.0.9/java.lang.invoke.MemberName$Factory.resolveOrFail(MemberName.java:1117)
    at java.base@17.0.9/java.lang.invoke.MethodHandles$Lookup.resolveOrFail(MethodHandles.java:3649)
    at java.base@17.0.9/java.lang.invoke.MethodHandles$Lookup.findVirtual(MethodHandles.java:2680)
    at io.micrometer.core.instrument.binder.cache.HazelcastIMapAdapter.resolveIMapMethod(HazelcastIMapAdapter.java:257)
    ... 53 more
Caused by: java.lang.NoSuchMethodError: com.hazelcast.map.IMap.getName()
    at org.graalvm.nativeimage.builder/com.oracle.svm.core.methodhandles.Util_java_lang_invoke_MethodHandleNatives.resolve(Target_java_lang_invoke_MethodHandleNatives.java:345)
    at java.base@17.0.9/java.lang.invoke.MethodHandleNatives.resolve(MethodHandleNatives.java:223)
    at java.base@17.0.9/java.lang.invoke.MemberName$Factory.resolve(MemberName.java:1085)
    at java.base@17.0.9/java.lang.invoke.MemberName$Factory.resolveOrFail(MemberName.java:1114)
    ... 56 more

Environment
Error happens on latest version of micrometer, coming from this line:
~https://github.com/micrometer-metrics/micrometer/blob/main/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/cache/HazelcastIMapAdapter.java#L53

static { GET_NAME = resolveIMapMethod("getName", methodType(String.class)); } (...) private static MethodHandle resolveIMapMethod(String name, MethodType mt) { try { return MethodHandles.publicLookup().findVirtual(CLASS_I_MAP, name, mt); } catch (NoSuchMethodException | IllegalAccessException e) { // "NoSuchMethodError" is thrown, not "NoSuchMethodException" throw new IllegalStateException(e); } }

To Reproduce
How to reproduce the bug:

Expected behavior
This reflective operation should be compatible with native image generation.

Additional context
Add any other context about the problem here, e.g. related issues.