failsafe-lib / failsafe

Fault tolerance and resilience patterns for the JVM
https://failsafe.dev
Apache License 2.0
4.16k stars 295 forks source link

dev.failsafe.Functions.* do not propagate toString to the wrapped object #372

Open zivkov opened 9 months ago

zivkov commented 9 months ago

The functions in dev.failsafe.Functions return a lambda which doesn't propagate the toString() to the wrapped object. This is an issue when an application wants to get toString() of the wrapped object for monitoring purposes. For example a subclass of ScheduledExecutorService may be created to decorate the tasks and provide reporting on submitted/pending tasks. Since toString() is not propagated we only see strings like Functions$$Lambda$9/0x0000000800067440@357246de.

To illustrate the issue here is a small example (without using Failsafe):

class MyTask implements Runnable {
  @Override
  public void run() {
    System.out.println("running");
  }

  @Override
  public String toString() {
    return "custom toString";
  }
}

class Functions {
  static Runnable wrap(Runnable r) {
    return () -> r.run();
  }
}

class FunctionsWithToString {
  static Runnable wrap(Runnable r) {
    return new Runnable() {
      @Override
      public void run() {
        r.run();
      }

      @Override
      public String toString() {
        return r.toString();
      }
    };
  }
}

public class TestRunnableToString {
  public static void main(String[] args) {
    Runnable unwrapped = new MyTask();
    System.out.printf("unwrapped.toString = %s\n", unwrapped.toString());

    Runnable wrapped = Functions.wrap(unwrapped);
    System.out.printf("wrapped.toString = %s\n", wrapped.toString());

    Runnable wrapped2 = FunctionsWithToString.wrap(unwrapped);
    System.out.printf("wrapped.toString = %s\n", wrapped2.toString());
  }
}

the output is:

unwrapped.toString = custom toString
wrapped.toString = Functions$$Lambda$9/0x0000000800067440@357246de
wrapped2.toString = custom toString