I'm using a 3rd party library and have discovered a performance bug in it during profiling. I can easily fix this by decompiling the offending class and changing the 'getFoo(Bar b)' method to use a LoadingCache. I then just put that file in the same package in my own source and it overrides it. However, the rest of the class is fine and I don't want to have to keep it updated with library updates.
(I'm aware that the function I'm manipulating may change in the future, but this is also a thought exercise as much as anything else)
What I'm looking for is a way to do this without decompiling the class, i.e. using AspectJ / Javassist / some other bytecode manipulator
e.g. change this:
public class SlowWorker{
    public static Foo getFoo(Bar b){
        //do long running op using b and return a Foo
    }
}
to:
public class SlowWorker{
    private static LoadingCache<AdviceDocument, Object> fooCache = CacheBuilder
      .newBuilder()
      .maximumSize(10000)
      .weakKeys()
      .build(new CacheLoader<Bar, Object>() {
            @Override
            public Object load(Bar b) throws Exception {
                return getUncachedFoo(b);
            }
        });
    public static Foo getFoo(Bar b){
        return fooCache.get(b);
    }
    public static Foo getUncachedFoo(Bar b){
        Foo result = //long running op on b
        return result;
    }
}
After a few hours of fiddling and researching, I realised that what I was trying to do was Hot-Swap the code.
For the curious:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With