1

I am creating a java framework to convert beans with the help of Invoke dynamic. I create the convert class with ASM. In order to generate a conversion which looks like:

target.setter( convert(source.getter()) );

I write the following bytecode with ASM:

mv.visitVarInsn(ALOAD, ARGUMENT_2);
mv.visitVarInsn(ALOAD, ARGUMENT_1);
mv.visitMethodInsn(INVOKEVIRTUAL, sourceClass, sourceGetter.getName(), Type.getMethodDescriptor(sourceGetter), false);
mv.visitInvokeDynamicInsn("convert", Type.getMethodDescriptor(Type.getType(targetSetter.getParameterTypes()[0]), Type.getType(sourceGetter.getReturnType())), converterBootstrapMethod);
mv.visitMethodInsn(INVOKEVIRTUAL, targetClass, targetSetter.getName(), Type.getMethodDescriptor(targetSetter), false);

The convert method then searches for a converter that can handle the given types. This looks like:

public static CallSite bootstrap(final MethodHandles.Lookup caller, final String name, final MethodType type) throws Exception {
    final Class<?> sourceType = type.parameterType(0);
    final Class<?> targetType = type.returnType();
    MethodHandle converter = findConverter(sourceType, targetType);
    return new ConstantCallSite( converter.asType(type) );
}

This works fine for say String to Integer conversion. But not for generics. The sourceType is only Ljava/util/List; and not the full Ljava/util/List<Ljava/lang/String;>;

How can I get the full type in this bootstrap method?

SPee
  • 656
  • 4
  • 5

1 Answers1

0

If you are in control of your invoke dynamic call site, you are able to pass additional arguments to it. Within these arguments, you would need to pass the actual field/getter names and their declaring classes to the callsite.

Using this information within your bootstrap method, you can now locate the actual fields/getters and extract the generic information via the reflection API.

Rafael Winterhalter
  • 42,759
  • 13
  • 108
  • 192