The example in "Working with unloaded classes" is wrong.
The example in "Working with unloaded classes" is wrong.
class MyApplication {
public static void main(String[] args) {
TypePool typePool = TypePool.Default.ofSystemLoader();
Class bar = new ByteBuddy()
.redefine(typePool.describe("foo.Bar").resolve(), // do not use 'Bar.class'
ClassFileLocator.ForClassLoader.ofSystemLoader())
.defineField("qux", String.class) // we learn more about defining fields later
.make()
.load(ClassLoader.getSystemClassLoader());
assertThat(bar.getDeclaredField("qux"), notNullValue());
}
}
How so? What is wrong with it?
Class bar = new ByteBuddy()
.redefine(typePool.describe("foo.Bar").resolve(), // do not use 'Bar.class'
ClassFileLocator.ForClassLoader.ofSystemLoader())
.defineField("qux", String.class) // we learn more about defining fields later
.make()
.load(ClassLoader.getSystemClassLoader()); // It returns net.bytebuddy.dynamic.DynamicType.Loaded, not Class.
If invoke getLoaded() method, then return the Class. But it throws an exception:
Class<?> loadedClass = new ByteBuddy()
.redefine(typePool.describe("foo.Bar").resolve(), // do not use 'Bar.class'
ClassFileLocator.ForClassLoader.ofSystemLoader())
.defineField("qux", String.class)
.make()
.load(ClassLoader.getSystemClassLoader())
.getLoaded(); // invoke the method to return Class. But the code throws Exception in thread "main" java.lang.IllegalStateException: Class already loaded: class foo.Bar
The log:
Exception in thread "main" java.lang.IllegalStateException: Class already loaded: class foo.Bar
at net.bytebuddy.dynamic.loading.ByteArrayClassLoader.load(ByteArrayClassLoader.java:362)
at net.bytebuddy.dynamic.loading.ClassLoadingStrategy$Default$WrappingDispatcher.load(ClassLoadingStrategy.java:367)
at net.bytebuddy.dynamic.loading.ClassLoadingStrategy$Default.load(ClassLoadingStrategy.java:148)
at net.bytebuddy.dynamic.TypeResolutionStrategy$Passive.initialize(TypeResolutionStrategy.java:101)
at net.bytebuddy.dynamic.DynamicType$Default$Unloaded.load(DynamicType.java:6166)
at net.bytebuddy.dynamic.DynamicType$Default$Unloaded.load(DynamicType.java:6154)
at com.diguage.cafe.jiadao.Test6.main(Test6.java:26)
$ java -version
openjdk version "1.8.0_332"
OpenJDK Runtime Environment Corretto-8.332.08.1 (build 1.8.0_332-b08)
OpenJDK 64-Bit Server VM Corretto-8.332.08.1 (build 25.332-b08, mixed mode)
byte-buddy.version: 1.12.12
I assume that you loaded the class somewhere in com.diguage.cafe.jiadao.Test6.main. There's a unit test to check that this works in Byte Buddy.
@raphw OK, let me research it.
I found the test example: https://github.com/raphw/byte-buddy/blob/master/byte-buddy-dep/src/test/java/net/bytebuddy/ByteBuddyTutorialExamplesTest.java#L155
The test example invokes .getLoaded():

There is one more difference:


I commented on your PR also. The test is different to keep it repeatable on the same VM. That's probably why this glitched through. Try the system loader with the INJECT strategy, then I think this would work.
That being the case, whether the tutorial can correspond to a specific version of byteBuddy, I think this is a good thing, if the sentence does not go smoothly, please forgive me for using google translate.