1

As the title says I'm trying to modify a method's annotation String parameter at runtime in Java on Android. I've found an answer to another question asked some time ago which should solve the problem. However, it didn't on Android. In the linked answer there is the following code line

Object handler = Proxy.getInvocationHandler(annotation);

It assigns a libcore.reflect.AnnotationFactory Object to the handler variable. Three lines later in the code it is tried to get the class's field "memberValues", which is said to provide the annotation's member-value-pairs. It is realized using this line of code:

f = handler.getClass().getDeclaredField("memberValues");

However, Android's AnnotationFactory class does not have a field named "memberValues". That's why I get an exception telling me: java.lang.NoSuchFieldException: No field memberValues in class Llibcore/reflect/AnnotationFactory; (declaration of 'libcore.reflect.AnnotationFactory' appears in /apex/com.android.art/javalib/core-libart.jar). Also, I cannot even access any declared fields of the class. I don't know why, but handler.getClass().getDeclaredFields() is empty, although handler.getClass() returns libcore.reflect.AnnotationFactory. I am trying to apply this runtime modification to the functionName value of a simple interface looking like this:

public interface LambdaFunctionInterface {
    @LambdaFunction(functionName = "PLACEHOLDER")
    Object lambdaFunction(Object request);
}

How can I realize it on Android? Where are the mentioned member-value-pairs of annotations stored on Android? Thanks a lot in advance!

Nico Feulner
  • 185
  • 3
  • 14
  • 1
    As you can see in the linked source code, there is a declaration `AnnotationMember[] elements` containing the data. This doesn’t imply that the runtime allows you to hack these values. – Holger Aug 17 '20 at 13:07
  • @Holger Exactly. In contrast to usual Java, annotations are fetched using a native method on Android. I guess I just didn't write my question precise enough. I know about the fact that I get an unmodifiable array of AnnotationMember objects back from Android's Java implementation if I fetch them using an instance of Method or Field. However, I would like to know if someone knows about a possibility to realize a modification anyway. Maybe some other kind of solution. Thanks anyway for your response! – Nico Feulner Aug 17 '20 at 14:30
  • 1
    But why do you want to modify what is supposed to be constant, immutable information? Do you like fighting the system? Whatever hack someone comes around with may break the next release (like the hacks for the other implementations do). What if the next version doesn’t even use `Proxy`? – Holger Aug 17 '20 at 15:18
  • My goal was to write an AWS-Lambda Flutter library using the Amazon's Android library as a base. The AWS library takes an interface with the name of the lambda that is to be called as input parameter. I wanted to write an interface that allows me to change the lambda name in the interface's annotation dynamically so I can take the function name as an input parameter from Flutter and pass it to the AWS library for the Android SDK. I ended up finding a different solution and published my library on pub.dev. However, I'm still interested in the question if changing the annotation is possible. – Nico Feulner Aug 19 '20 at 13:04

0 Answers0