title: How to Dynamically Extend Concrete Classes with ByteBuddy
body: <p>I've been playing with the ByteBuddy library for a while and I find myself stuck. I had this method working when the tested classes were within the same file (as static inner classes), but now that I've separated the logic into a separate file, it's no longer working.</p>
  
  <p>If it helps (and maybe I'm taking the wrong approach), my goal is to make a dynamic subclass of the input Class <code>originalClazz</code> and store a reference to the <code>originalClazz</code> Class object, plus a reference to the input object <code>original</code>.
  I use the <code>ProxyHandler.execute</code> method to call methods on the <code>original</code> object directly and wrap the return value in a proxy (also using <code>proxyMe</code>). </p>
  
  <p>The following block is all in one java file:</p>
  
  <pre><code>private static final String ORIGINAL_OBJECT_FIELD_NAME = "_original_object_";
  private static final String ORIGINAL_CLASS_FIELD_NAME = "_original_class_";
  
  public static &lt;T&gt; T proxyMe(final T original, final Class&lt;?&gt; originalClazz) {
      if (originalClazz != null &amp;&amp; isNotFinal(originalClazz) &amp;&amp; hasDefaultConstructor(originalClazz)) {
          try {
              final Class&lt;?&gt; newSubClass = new ByteBuddy()
                      .subclass(originalClazz, ConstructorStrategy.Default.NO_CONSTRUCTORS)
                      .defineField(ORIGINAL_OBJECT_FIELD_NAME, Object.class, Visibility.PUBLIC)
                      .defineField(ORIGINAL_CLASS_FIELD_NAME, Class.class, Visibility.PUBLIC)
                      .method(any())
                          .intercept(to(ProxyHandler.class))
                      .defineConstructor(Visibility.PUBLIC)
                          .intercept(MethodCall.invoke(originalClazz.getConstructor()))
                      .make()                                // &lt;-- exception thrown here
                      .load(originalClazz.getClassLoader())
                      .getLoaded();
  
              final Object result = newSubClass.newInstance();
              setField(result, ORIGINAL_OBJECT_FIELD_NAME, original);
              setField(result, ORIGINAL_CLASS_FIELD_NAME, originalClazz);
              return (T) result;
          } catch (NoSuchMethodException | InstantiationException | IllegalAccessException e) {
              e.printStackTrace();
          }
      }
      return original;
  }
  
  public static class ProxyHandler {
      @RuntimeType
      public static Object execute(
          @SuperCall Callable&lt;Object&gt; callable,
          @This Object obj,
          @Origin Method method,
          @AllArguments Object[] arguments
      ) {
          ...
      }
  }
  </code></pre>
  
  <p>And in my test class...</p>
  
  <pre><code>@Test
  public void makeProxy() throws Exception {
      final Foo foo = new Foo(new Bar("str"));
      proxyMe(foo, Foo.class);
  }
  
  public static class Bar {
      private String name;
      public Bar() {}
      public Bar(final String name) { this.name = name; }
      public String getName() { return name; }
  }
  
  public static class Foo {
      private Bar bar;
      public Foo() {}
      public Foo(final Bar bar) { this.bar = bar; }
      public Bar getBar() { return bar; }
  }
  </code></pre>
  
  <p>Exception thrown:</p>
  
  <pre><code>None of [
    TargetMethodAnnotationDrivenBinder.Record{
      ,
      candidate=public static java.lang.Object somepackage.Utils$ProxyHandler.execute(
        java.util.concurrent.Callable,
        java.lang.Object,
        java.lang.reflect.Method,
        java.lang.Object[]
      ),
      handlers=[
        TargetMethodAnnotationDrivenBinder.DelegationProcessor.Handler.Bound{
          parameterBinder=SuperCall.Binder.INSTANCE,
          annotation=@net.bytebuddy.implementation.bind.annotation.SuperCall(
            serializableProxy=false,
            nullIfImpossible=false,
            fallbackToDefault=true
          ),
          target=java.util.concurrent.Callable arg0,
          typing=Assigner.Typing.STATIC
        },
        TargetMethodAnnotationDrivenBinder.DelegationProcessor.Handler.Bound{
          parameterBinder=This.Binder.INSTANCE,
          annotation=@net.bytebuddy.implementation.bind.annotation.This(
            optional=false
          ),
          target=java.lang.Object arg1,
          typing=Assigner.Typing.STATIC
        },
        TargetMethodAnnotationDrivenBinder.DelegationProcessor.Handler.Bound{
          parameterBinder=Origin.Binder.INSTANCE,
          annotation=@net.bytebuddy.implementation.bind.annotation.Origin(
            cache=true
          ),
          target=java.lang.reflect.Method arg2,
          typing=Assigner.Typing.STATIC
        },
        TargetMethodAnnotationDrivenBinder.DelegationProcessor.Handler.Bound{
          parameterBinder=AllArguments.Binder.INSTANCE,
          annotation=
            @net.bytebuddy.implementation.bind.annotation.AllArguments(
              value=STRICT,
              includeSelf=false
            ),
          target=[Ljava.lang.Object; arg3, typing=Assigner.Typing.STATIC}],
          typing=Assigner.Typing.DYNAMIC
        }
      ]
      allows for delegation from public somepackage.UtilsTest$Bar somepackage.UtilsTest$Foo.getBar()
  </code></pre>