Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document is hard to read #661

Open
harrybin815 opened this issue May 30, 2019 · 6 comments
Open

Document is hard to read #661

harrybin815 opened this issue May 30, 2019 · 6 comments
Assignees
Milestone

Comments

@harrybin815
Copy link

  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
Copy link
Author

.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.

@raphw
Copy link
Owner

raphw commented May 30, 2019

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 raphw self-assigned this May 30, 2019
@raphw raphw added the question label May 30, 2019
@raphw raphw added this to the 1.9.13 milestone May 30, 2019
@harrybin815
Copy link
Author

Thanks for answering questions and considering Suggestions

@harrybin815
Copy link
Author

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
Copy link
Author

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
Copy link
Author

@raphw

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants