# Change private class-fields with Advice.FieldValue and inline = true with IndyBootstrap

**URL:** <https://discuss.elastic.co/t/change-private-class-fields-with-advice-fieldvalue-and-inline-true-with-indybootstrap/279646>\
**Category:** APM\
**Tags:** java\
**Created:** [July 26, 2021, 3:06pm UTC](https://discuss.elastic.co/t/change-private-class-fields-with-advice-fieldvalue-and-inline-true-with-indybootstrap/279646 "2021-07-26T15:06:03Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![milanvdm](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/milanvdm/32/82732_2.png) [@milanvdm](https://discuss.elastic.co/u/milanvdm)\
**Post date:** [July 26, 2021, 3:06pm UTC](https://discuss.elastic.co/t/change-private-class-fields-with-advice-fieldvalue-and-inline-true-with-indybootstrap/279646/1 "2021-07-26T15:06:03Z")

</div>

I would like to do the following:

```auto
@Advice.OnMethodExit(suppress = Throwable.class, inline = true)
        public static void onExit(
            @Advice.Enter @Nullable Object abstractSpanObj,
            @Advice.This Object thiz,
            @Advice.FieldValue(value = "localState", readOnly = false) Map<IOLocal<?>, Object> localState
        )

```

As far as I understand, you can only set `readOnly = false` on a private field of a class when the `Advice` is inlined. The problem is that it cannot be inlined due to the IndyBootstrap.

How can we change private fields of classes with this approach? Or is this a limitation of the ElasticAPM intrumentation?

It seems to be related to: [Customizable advice dispatcher · Issue #830 · raphw/byte-buddy · GitHub](https://github.com/raphw/byte-buddy/issues/830)

---

<div class="post-metadata">

**Author:** ![Eyal\_Koren](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/eyal_koren/32/36830_2.png) [@Eyal\_Koren](https://discuss.elastic.co/u/Eyal_Koren)\
**Post date:** [July 27, 2021, 6:11am UTC](https://discuss.elastic.co/t/change-private-class-fields-with-advice-fieldvalue-and-inline-true-with-indybootstrap/279646/2 "2021-07-27T06:11:54Z")

</div>

You are right, in Indy plugins, the way to assign values to fields is done this way: [apm-agent-java/InstrumentationTest.java at b0dbda275335adf618d1e4c8fc94a53ce19f6764 · elastic/apm-agent-java · GitHub](https://github.com/elastic/apm-agent-java/blob/b0dbda275335adf618d1e4c8fc94a53ce19f6764/apm-agent-core/src/test/java/co/elastic/apm/agent/bci/InstrumentationTest.java#L565-L611)

---

<div class="post-metadata">

**Author:** ![milanvdm](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/milanvdm/32/82732_2.png) [@milanvdm](https://discuss.elastic.co/u/milanvdm)\
**Post date:** [July 27, 2021, 7:22am UTC](https://discuss.elastic.co/t/change-private-class-fields-with-advice-fieldvalue-and-inline-true-with-indybootstrap/279646/3 "2021-07-27T07:22:45Z")

</div>

Im not sure on how to use it. I tried:

```auto
        @AssignTo(fields = @AssignTo.Field(index = 3, value = "localState"))
        @Advice.OnMethodExit(suppress = Throwable.class, inline = false)
        public static void onExit(
            @Advice.Enter @Nullable Object abstractSpanObj,
            @Advice.This Object thiz,
            @Advice.Argument(3) Object localStateObj
        )

```

I assigned it to index 3 as the method Im trying to instrument already has 3 arguments but then I get an exception that index 3 isnt defined.

How can I retrieve the assigned field from the annotation?

---

<div class="post-metadata">

**Author:** ![Eyal\_Koren](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/eyal_koren/32/36830_2.png) [@Eyal\_Koren](https://discuss.elastic.co/u/Eyal_Koren)\
**Post date:** [July 27, 2021, 7:59am UTC](https://discuss.elastic.co/t/change-private-class-fields-with-advice-fieldvalue-and-inline-true-with-indybootstrap/279646/4 "2021-07-27T07:59:57Z")

</div>

The advice method returns the value that should be assigned to the filed. The linked tests show two forms:

1. If you only want to assign to a field, your advice method will return the value to assign and you don't need to specify index
2. If you want to assign to multiple things, your advice method needs to return an `Object[]` and the `index` specifies what value from the returned array needs to be assigned to the corresponding field.

I hope this helps

---

<div class="post-metadata">

**Author:** ![milanvdm](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/milanvdm/32/82732_2.png) [@milanvdm](https://discuss.elastic.co/u/milanvdm)\
**Post date:** [July 27, 2021, 8:18am UTC](https://discuss.elastic.co/t/change-private-class-fields-with-advice-fieldvalue-and-inline-true-with-indybootstrap/279646/5 "2021-07-27T08:18:12Z")

</div>

Im still quite confused on the usage tbh 🙂

```auto
class MyInstrumentation extends ElasticApmInstrumentation {
 
        @AssignTo.Field("privateString")
        @Advice.OnMethodEnter
        public static String getPrivateString(@Advice.Argument(0) String s) {
            return s;
        }

        @Advice.OnMethodExit(suppress = Throwable.class, inline = false)
        public static void onExit(
            @Advice.Enter @Nullable Object abstractSpanObj,
            @Advice.This Object thiz
        ) { getPrivateString() }

}

```

How would you change the value of this private field during runtime with this approach?

---

<div class="post-metadata">

**Author:** ![milanvdm](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/milanvdm/32/82732_2.png) [@milanvdm](https://discuss.elastic.co/u/milanvdm)\
**Post date:** [July 27, 2021, 11:43am UTC](https://discuss.elastic.co/t/change-private-class-fields-with-advice-fieldvalue-and-inline-true-with-indybootstrap/279646/6 "2021-07-27T11:43:18Z")

</div>

I think I figured it out, let me know if this makes sense:

```auto
class MyInstrumentation extends ElasticApmInstrumentation {
 
        @AssignTo.Field("localState")
        @Advice.OnMethodExit(suppress = Throwable.class, inline = false)
        public static Map<IOLocal<?>, Object> onExit(
            @Advice.Enter @Nullable Object abstractSpanObj,
            @Advice.This Object thiz,
            @Advice.FieldValue(value = "localState") Map<IOLocal<?>, Object> localState
        ) { return localState.updated("foo", "bar" }

}

```

---

<div class="post-metadata">

**Author:** ![Eyal\_Koren](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/eyal_koren/32/36830_2.png) [@Eyal\_Koren](https://discuss.elastic.co/u/Eyal_Koren)\
**Post date:** [July 27, 2021, 1:50pm UTC](https://discuss.elastic.co/t/change-private-class-fields-with-advice-fieldvalue-and-inline-true-with-indybootstrap/279646/7 "2021-07-27T13:50:49Z")

</div>

Yes, assuming that the `localState` field's type is `Map<IOLocal<?>, Object>` and this is also what is being returned from `localState.updated("foo", "bar")`.  
If it works, then it's probably right 🙂

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [August 17, 2021, 9:51am UTC](https://discuss.elastic.co/t/change-private-class-fields-with-advice-fieldvalue-and-inline-true-with-indybootstrap/279646/8 "2021-08-17T09:51:25Z")

</div>

This topic was automatically closed 20 days after the last reply. New replies are no longer allowed.
