byte-buddy icon indicating copy to clipboard operation
byte-buddy copied to clipboard

Document is hard to read

Open harrybin815 opened this issue 6 years ago • 6 comments

  1. Missing is a description of each component and its common methods (like TypePool, DynamicType, ClassLoadingStrategy etc.)
  2. Class calls may vary from version to version, such as the current version is:
package foo;
class Bar { }
class MyApplication {
  public static void main(String[] args) {
    TypePool typePool = TypePool.Default.ofClassPath();
    new ByteBuddy()
      .redefine(typePool.describe("foo.Bar").resolve(), // do not use 'Bar.class'
                ClassFileLocator.ForClassLoader.ofClassPath())
      .defineField("qux", String.class) // we learn more about defining fields later
      .make()
      .load(ClassLoader.getSystemClassLoader());
    assertThat(Bar.class.getDeclaredField("qux"), notNullValue());
  }
}

It was not compiled in 1.9.13, but the 1.9.13 version of the document could not be found. Try to change it to:

package foo;
class Bar { }
class MyApplication {
  public static void main(String[] args) {
    TypePool typePool = TypePool.Default.of(Thread.currentThread().getContextClassLoader());
    new ByteBuddy()
      .redefine(typePool.describe("foo.Bar").resolve(), // do not use 'Bar.class'
                ClassFileLocator.ForClassLoader.of(Thread.currentThread().getContextClassLoader()))
      .defineField("qux", String.class) // we learn more about defining fields later
      .make()
      .load(ClassLoader.getSystemClassLoader());
     assertThat(Bar.class.getDeclaredField("qux"), notNullValue());
  }
}

But in the end:

Exception in thread "main" java.lang.IllegalStateException: Class already loaded: foo.Bar

Much more complex than using javassist

harrybin815 avatar May 30 '19 12:05 harrybin815

.load(ClassLoader.getSystemClassLoader(), ClassLoadingStrategy.Default.INJECTION); 

So it works. By passing ClassLoadingStrategy.Default.INJECTION.

the default ClassLoadingStrategy.Default.WRAPPER use another ByteArrayClassLoader and it's parent is SystemLoader.

harrybin815 avatar May 30 '19 13:05 harrybin815

A feature was added to Byte Buddy that throws an exception if a class that is injected is already loaded. In Byte Buddy 1.9.*, any use unsafe (unofficial) API is opt-in, therefore, INJECTION is no longer the default.

But you are right, there should be more documentation, I simply lack the time to write it.

raphw avatar May 30 '19 14:05 raphw

Thanks for answering questions and considering Suggestions

harrybin815 avatar May 31 '19 02:05 harrybin815

The examples from Section "Accessing fields" of this tutorial (http://bytebuddy.net/#/tutorial) will not work in version 1.9.13.

When running to

        InstanceCreator factory = new ByteBuddy()
                .subclass(InstanceCreator.class)
                .method(not(isDeclaredBy(Object.class)))
                .intercept(MethodDelegation.toConstructor(dynamicUserType))
                .make()
                .load(I.class.getClassLoader())
                .getLoaded()
                .newInstance();

An exception is thrown here, beause:

MethodDelegationBinder$Processor#bind(Implementation.Target implementationTarget,
                                  MethodDescription source,
                                  TerminationHandler terminationHandler,
                                  MethodInvoker methodInvoker,
                                  Assigner assigne)

How to solve this problem?

harrybin815 avatar Jun 03 '19 10:06 harrybin815

in @Argumen$Binder#bind(...) :

Argument argument = annotation.loadSilent();
            if (argument.value() < 0) {
                throw new IllegalArgumentException("@Argument annotation on " + target + " specifies negative index");
            } else if (source.getParameters().size() <= argument.value()) {
                return MethodDelegationBinder.ParameterBinding.Illegal.INSTANCE;
            }

source.getParameters().size() <= argument.value() make this exception.

  1. source is InstanceCreator and it's argument length is empty,
  2. argument.value() also zero In such a case, the judgment must be illegal. The logic here is confusing to me.

harrybin815 avatar Jun 03 '19 10:06 harrybin815

@raphw

harrybin815 avatar Jun 03 '19 10:06 harrybin815