graal icon indicating copy to clipboard operation
graal copied to clipboard

[GR-45258] MethodHandle on getter returns 0(false) instead of null for Long/Integer/Boolean using native-image

Open dagrammy opened this issue 3 years ago • 5 comments

Describe the issue Invoking a MethodHandle on a method with Long as return type returns 0 instead of null using native-image.

This can also be reproduced using Integer and Boolean as return type.

Steps to reproduce the issue I added a reproducer, see https://github.com/dagrammy/graal-native-bug-test git clone https://github.com/dagrammy/graal-native-bug-test.git and follow the steps in the readme https://github.com/dagrammy/graal-native-bug-test/blob/main/README.md

Describe GraalVM and your environment:

  • GraalVM version: graalvm-ce-java17-22.3.0
  • JDK major version: 17
  • OS: macOS Ventura 13.0.1
  • Architecture: arm/Apple M1

More details Full example can be found here: https://github.com/dagrammy/graal-native-bug-test

This is a simple Pojo bean:

public class BeanLong {
  private Long value = null;

  public BeanLong() {
  }

  public Long getValue() {
    return value;
  }
}

The getter is invoked using a MethodHandle:

    Class<?> beanClass = BeanLong.class;
    Object bean = new BeanLong();

    Method method = beanClass.getMethod("getValue");
    MethodHandle methodHandle = MethodHandles.publicLookup().unreflect(method);

    // Call to MH returns 0 in native mode instead of null
    Long out = (Long) methodHandle.invoke(bean);
    System.out.println(">>>>> " + out + " <<<<<");

Output in JVM:

>>>>> null <<<<<

Output in native-image:

>>>>> 0 <<<<<

Using MethodHandles.publicLookup().findVirtual(beanClass, "getValue", MethodType.methodType(Long.class)); instead of unreflect also shows this behaviour (s. reproducer).

Maybe issue https://github.com/oracle/graal/issues/5209 is related?

dagrammy avatar Dec 23 '22 10:12 dagrammy

@fniephaus @loicottet Happy new year :) I just wanted to ask if either one of you had time to check this issue. A short response is sufficient enough. Thx!

hamburml avatar Jan 03 '23 16:01 hamburml

I haven't had a chance to look at it yet. At first glance this looks like an issue in the way our method handle implementation handles boxing of primitive return values rather than #5209 but I will need to look into it further to confirm.

loicottet avatar Jan 04 '23 12:01 loicottet

I am seeing the same issue - would be great to see it fixed 👍

ygyg70 avatar Mar 30 '23 01:03 ygyg70

Hello all,

is there any news on this topic?

The PR https://github.com/objectify/objectify/pull/490 by @ygyg70 seems to fix the problem. Would it be possible to merge the PR or are there concerns?

dagrammy avatar May 22 '23 07:05 dagrammy

There are some discussions on the PR https://github.com/objectify/objectify/pull/490

ygyg70 avatar Jul 26 '24 02:07 ygyg70

Hey @dagrammy I cannot reproduce the problem on current versions. I have tried with our master branch and also on 17.0.16+12

I believe we have fixed that along the way.

$ ./methodhandletestall
------ Test with Long --------
without MethodHandle
>>>>>null<<<<<
got Long MethodHandle by unreflect
>>>>>null<<<<<
got Long MethodHandle by findVirtual
>>>>>null<<<<<
------ Test with Integer --------
without MethodHandle
>>>>>null<<<<<
got Integer MethodHandle by unreflect
>>>>>null<<<<<
got Integer MethodHandle by findVirtual
>>>>>null<<<<<
------ Test with Boolean --------
without MethodHandle
>>>>>null<<<<<
got Boolean MethodHandle by unreflect
>>>>>null<<<<<
got Boolean MethodHandle by findVirtual
>>>>>null<<<<<
------ Test with String --------
without MethodHandle
>>>>>null<<<<<
got String MethodHandle by unreflect
>>>>>null<<<<<
got String MethodHandle by findVirtual
>>>>>null<<<<<

wirthi avatar Jul 17 '25 19:07 wirthi