# Plugin: WARN: End has already been called

**URL:** <https://discuss.elastic.co/t/plugin-warn-end-has-already-been-called/288837>\
**Category:** APM\
**Tags:** java\
**Created:** [November 10, 2021, 3:14am UTC](https://discuss.elastic.co/t/plugin-warn-end-has-already-been-called/288837 "2021-11-10T03:14:46Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Matthias\_W](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/matthias_w/32/96451_2.png) [@Matthias\_W](https://discuss.elastic.co/u/Matthias_W)\
**Post date:** [November 10, 2021, 3:14am UTC](https://discuss.elastic.co/t/plugin-warn-end-has-already-been-called/288837/1 "2021-11-10T03:14:46Z")

</div>

Hi,

I have developed a small instrumentation plugin for the Java APM agent.

The advice class follows the pattern suggested in the documentation:

```auto
public static class AdviceClass
{
  @Advice.OnMethodEnter(suppress = Throwable.class, inline = false)
  public static Object onBeforeExecute()
  {
    Span active = ElasticApm.currentSpan();
    // ...
    Span span = active.startExitSpan(type, subtype, action);
    span.setName("SPANNAME");

    return span.activate();
  }

  @Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class, inline = false)
  public static void onAfterExecute(@Advice.Enter Object obj, @Advice.Thrown Throwable t)
  {
    if (!(obj instanceof Scope))
      return;

    Span span = ElasticApm.currentSpan();
    try (Scope scope = (Scope) obj)
    {
      if (t != null)
      {
        span.setOutcome(Outcome.FAILURE);
        span.captureException(t);
      }
    }
    finally
    {
      span.end();
    }
 }

```

Everything seems to work fine - I can see the Spans in the APM dashboard.

However, I keep getting a warning messages:

> WARN co.elastic.apm.agent.impl.transaction.AbstractSpan - End has already been called: 'SPANNAME'

What is wrong with my code?

---

<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:** [November 10, 2021, 8:33am UTC](https://discuss.elastic.co/t/plugin-warn-end-has-already-been-called/288837/2 "2021-11-10T08:33:17Z")

</div>

If you use `debug` log level, you would see all starts and ends of each span printed with the trace context and the object identity hash code, so you can follow it. If you use `trace` level, it would print stack traces as well.  
Try to execute as little invocations of the instrumentation as possible (ideally only one) because this would be quite verbose.  
I hope this helps.

---

<div class="post-metadata">

**Author:** ![Matthias\_W](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/matthias_w/32/96451_2.png) [@Matthias\_W](https://discuss.elastic.co/u/Matthias_W)\
**Post date:** [November 26, 2021, 2:50am UTC](https://discuss.elastic.co/t/plugin-warn-end-has-already-been-called/288837/3 "2021-11-26T02:50:02Z")

</div>

I wasn't really able to pinpoint want went wrong exactly, but after changing my plugin to the following, the warning has disappeared:

```auto
  @Advice.OnMethodEnter(suppress = Throwable.class, inline = false)
  public static Object onBeforeExecute()
  {
    //...

    Scope scope = span.activate();
    // Note: Pair.of (from apache commons would work too - however, the following doesn't have any external dependencies):
    return new AbstractMap.SimpleImmutableEntry<>(span, scope);
  }

  @Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class, inline = false)
  public static void onAfterExecute(@Advice.Enter Object obj, @Advice.Thrown Throwable t)
  {
    Entry<Span, Scope> pair = (Entry<Span, Scope>) obj;

    Span span = entry.getKey();
    try (Scope scope = entry.getValue())
    {
      //...
    }
    finally
    {
      span.end();
    }
 }

```

Apparently, closing the current span in a plugin seems to be a bad idea.

---

<div class="post-metadata">

**Author:** ![tstadler](https://avatars.discourse-cdn.com/v4/letter/t/aca169/32.png) [@tstadler](https://discuss.elastic.co/u/tstadler)\
**Post date:** [November 28, 2021, 11:11am UTC](https://discuss.elastic.co/t/plugin-warn-end-has-already-been-called/288837/4 "2021-11-28T11:11:49Z")

</div>

Does

```auto
@Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class, inline = false)
  public static void onAfterExecute(@Advice.Enter Object obj, @Advice.Thrown Throwable t)
  {
    if (!(obj instanceof Scope))
      return;

    Span span = ElasticApm.currentSpan();
    try
    {
      if (t != null)
      {
        span.setOutcome(Outcome.FAILURE);
        span.captureException(t);
      }
      span.end();
    }
    finally
    {
      ((Scope) obj).close();
    }
 }

```

work?

---

<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:** [December 19, 2021, 7:12am UTC](https://discuss.elastic.co/t/plugin-warn-end-has-already-been-called/288837/5 "2021-12-19T07:12:43Z")

</div>

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