Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
blaghed opened this issue Oct 24, 2024 · 7 comments · Fixed by #5618
Closed
Labels
bug A general bug instrumentation An issue that is related to instrumenting a component module: micrometer-core An issue that is related to our core module theme: native-image Issues related to GraalVM native or Project Leyden
Milestone

Comments

@blaghed
Copy link

blaghed commented Oct 24, 2024

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.

@jonatan-ivanov
Copy link
Member

Could you please provide a minimal sample project to reproduce this issue so we can more easily investigate and ensure any fix is working properly for your use case?
The "How to reproduce the bug" section is rather an important one especially in this case with lots of moving parts (native-image, hazelcast, boot, etc.)

@jonatan-ivanov jonatan-ivanov added waiting for feedback We need additional information before we can continue and removed waiting-for-triage labels Oct 24, 2024
@jonatan-ivanov
Copy link
Member

jonatan-ivanov commented Oct 24, 2024

This is how far I got with my sample: https://github.com/jonatan-ivanov/ecoli/tree/gh-micrometer-5604-hazelcast-native-image

It seems either the Hazelcast version (5.4.0) that the latest Boot version (3.3.5) brings in does not work with native-image or I'm doing something wrong in the sample:

Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'hazelcastInstance': Instantiation of supplied bean failed
[...]
Caused by: java.lang.ExceptionInInitializerError
[...]
Caused by: com.hazelcast.core.HazelcastException: java.lang.NoSuchFieldException: ARTIFACT_ID
[...]
Caused by: java.lang.NoSuchFieldException: ARTIFACT_ID
	at java.base@22.0.2/java.lang.Class.checkField(DynamicHub.java:1051)
	at java.base@22.0.2/java.lang.Class.getField(DynamicHub.java:1036)
	at com.hazelcast.instance.BuildInfoProvider.readStaticStringField(BuildInfoProvider.java:109)
	... 39 more

The fix is probably fairly simple in Micrometer (we can add runtime hints) but we will need a reproducer first.

izeye added a commit to izeye/hello-hazelcast-java-client that referenced this issue Oct 31, 2024
@izeye
Copy link
Contributor

izeye commented Oct 31, 2024

I tried to reproduce it with Hazelcast 5.5.0 but got the same failure as @jonatan-ivanov got above.

I was able to reproduce it with Hazelcast 5.2.1 that GraalVM reachability metadata has been tested against.

See https://github.com/izeye/hello-hazelcast-java-client/tree/native-image-micrometer

@izeye
Copy link
Contributor

izeye commented Nov 1, 2024

I created #5618 to try to resolve this.

@izeye
Copy link
Contributor

izeye commented Nov 1, 2024

"java.lang.NoSuchFieldException: ARTIFACT_ID" seems to have been fixed in hazelcast/hazelcast@f2ff3be that hasn't been released yet.

See hazelcast/hazelcast#26386

@jonatan-ivanov
Copy link
Member

Thank you very much @izeye!

It seems the highest version that is not broken with ARTIFACT_ID is 5.3.8. 5.4.0 and above is broken. Also, it seems the oldest supported version of Boot (3.2.x) supports Hazelcast 5.3 and it is the current minor what Micrometer also uses so I thing that would be the version I would target for this.

Thank you for the PR, I will look into it soon.

@jonatan-ivanov jonatan-ivanov added enhancement A general enhancement and removed waiting for feedback We need additional information before we can continue labels Nov 1, 2024
@jonatan-ivanov jonatan-ivanov added this to the 1.15.0-M1 milestone Nov 1, 2024
@jonatan-ivanov jonatan-ivanov added bug A general bug and removed enhancement A general enhancement labels Nov 1, 2024
@jonatan-ivanov jonatan-ivanov modified the milestones: 1.15.0-M1, 1.12.x Nov 1, 2024
@blaghed
Copy link
Author

blaghed commented Nov 4, 2024

Hi,

Sorry for not answering the questions, fortunately you got to the answers quite fast.

Out of curiosity, did you report the "NoSuchFieldException" to Hazelcast?
Edit: Nevermind, you already referenced the Hazelcast ticket in your replies.

Thank you so much!

izeye added a commit to izeye/micrometer that referenced this issue Nov 7, 2024
@shakuzen shakuzen modified the milestones: 1.12.x, 1.12.12 Nov 11, 2024
@shakuzen shakuzen added module: micrometer-core An issue that is related to our core module theme: native-image Issues related to GraalVM native or Project Leyden instrumentation An issue that is related to instrumenting a component labels Nov 11, 2024
@shakuzen shakuzen changed the title Native Image / Spring Boot / Hazelcast: java.lang.NoSuchMethodError: com.hazelcast.map.IMap.getName() Native Image Hazelcast error: java.lang.NoSuchMethodError: com.hazelcast.map.IMap.getName() Nov 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A general bug instrumentation An issue that is related to instrumenting a component module: micrometer-core An issue that is related to our core module theme: native-image Issues related to GraalVM native or Project Leyden
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants