Skip to content

Commit 5f94c17

Browse files
committed
Fix use of ASM class reader and writer.
1 parent 7c8a4c2 commit 5f94c17

File tree

3 files changed

+64
-14
lines changed

3 files changed

+64
-14
lines changed

byte-buddy-dep/src/main/java/net/bytebuddy/utility/AsmClassReader.java

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@
3232
*/
3333
public interface AsmClassReader {
3434

35+
/**
36+
* Indicates that no custom attributes should be mapped.
37+
*/
38+
Attribute[] NO_ATTRIBUTES = new Attribute[0];
39+
3540
/**
3641
* Unwraps a class reader to the underlying reader mechanism.
3742
*
@@ -138,7 +143,9 @@ public AsmClassReader make(byte[] binaryRepresentation, boolean experimental) {
138143
* {@inheritDoc}
139144
*/
140145
public AsmClassReader make(byte[] binaryRepresentation, boolean experimental) {
141-
return new AsmClassReader.ForClassFileApi(ForClassFileApi.DISPATCHER.make(binaryRepresentation));
146+
return new AsmClassReader.ForClassFileApi(ForClassFileApi.DISPATCHER.make(
147+
binaryRepresentation,
148+
NO_ATTRIBUTES));
142149
}
143150
};
144151

@@ -187,11 +194,6 @@ public AsmClassReader make(byte[] binaryRepresentation) {
187194
*/
188195
class ForAsm implements AsmClassReader {
189196

190-
/**
191-
* Indicates that no custom attributes should be mapped.
192-
*/
193-
private static final Attribute[] NO_ATTRIBUTES = new Attribute[0];
194-
195197
/**
196198
* The class reader that represents the class file to be read.
197199
*/
@@ -271,7 +273,9 @@ private static <T> T doPrivileged(PrivilegedAction<T> action) {
271273
*/
272274
@MaybeNull
273275
public <T> T unwrap(Class<T> type) {
274-
return null;
276+
return type.isInstance(classReader)
277+
? type.cast(classReader)
278+
: null;
275279
}
276280

277281
/**
@@ -293,17 +297,18 @@ protected interface JdkClassReader {
293297
* @param value The instance to evaluate.
294298
* @return {@code true} if the supplied object is an instance of {@code codes.rafael.asmjdkbridge.JdkClassReader}.
295299
*/
296-
@JavaDispatcher.IsConstructor
300+
@JavaDispatcher.Instance
297301
boolean isInstance(Object value);
298302

299303
/**
300304
* Creates an instance of {@code codes.rafael.asmjdkbridge.JdkClassReader}.
301305
*
302306
* @param binaryRepresentation The binary representation of a class file to represent through the reader.
307+
* @param attribute An array of attribute prototypes.
303308
* @return A new instance of {@code codes.rafael.asmjdkbridge.JdkClassReader}.
304309
*/
305310
@JavaDispatcher.IsConstructor
306-
Object make(byte[] binaryRepresentation);
311+
Object make(byte[] binaryRepresentation, Attribute[] attribute);
307312

308313
/**
309314
* Accepts a class reader to visit the represented class file.

byte-buddy-dep/src/main/java/net/bytebuddy/utility/AsmClassWriter.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,8 @@ public AsmClassWriter make(int flags, AsmClassReader classReader, TypePool typeP
168168
SuperClassResolvingJdkClassWriter.GET_SUPER_CLASS,
169169
new SuperClassResolvingJdkClassWriter(typePool)));
170170
} else {
171-
return new ForClassFileApi(ForClassFileApi.DISPATCHER.make(flags,
172-
jdkClassReader,
171+
return new ForClassFileApi(ForClassFileApi.DISPATCHER.make(jdkClassReader,
172+
flags,
173173
SuperClassResolvingJdkClassWriter.GET_SUPER_CLASS,
174174
new SuperClassResolvingJdkClassWriter(typePool)));
175175
}
@@ -439,15 +439,15 @@ protected interface JdkClassWriter {
439439
/**
440440
* Create a new {@code codes.rafael.asmjdkbridge.JdkClassWriter}.
441441
*
442-
* @param flags The flags to consider.
443442
* @param classReader The class reader of which to reuse the constant pool.
443+
* @param flags The flags to consider.
444444
* @param getSuperClass A resolver for the super class.
445445
* @param target The target to invoke the super class resolver upon.
446446
* @return A new {@code codes.rafael.asmjdkbridge.JdkClassWriter}.
447447
*/
448448
@JavaDispatcher.IsConstructor
449-
ClassVisitor make(int flags,
450-
@JavaDispatcher.Proxied("codes.rafael.asmjdkbridge.JdkClassReader") Object classReader,
449+
ClassVisitor make(@JavaDispatcher.Proxied("codes.rafael.asmjdkbridge.JdkClassReader") Object classReader,
450+
int flags,
451451
Method getSuperClass,
452452
Object target);
453453

byte-buddy-dep/src/test/java/net/bytebuddy/ByteBuddyTest.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
import net.bytebuddy.implementation.StubMethod;
1010
import net.bytebuddy.matcher.ElementMatchers;
1111
import net.bytebuddy.test.utility.JavaVersionRule;
12+
import net.bytebuddy.utility.AsmClassReader;
13+
import net.bytebuddy.utility.AsmClassWriter;
1214
import org.junit.Rule;
1315
import org.junit.Test;
1416

@@ -199,6 +201,49 @@ public void testCallerSuffixNamingStrategy() throws Exception {
199201
+ "$testCallerSuffixNamingStrategy$SuffixedName"));
200202
}
201203

204+
@Test
205+
@JavaVersionRule.Enforce(24)
206+
public void testCanUseClassFileApiReaderAndWriter() throws Exception {
207+
Class<?> type = new ByteBuddy()
208+
.with(AsmClassReader.Factory.Default.CLASS_FILE_API_ONLY)
209+
.with(AsmClassWriter.Factory.Default.CLASS_FILE_API_ONLY)
210+
.redefine(Recorder.class)
211+
.make()
212+
.load(ClassLoadingStrategy.BOOTSTRAP_LOADER, ClassLoadingStrategy.Default.WRAPPER)
213+
.getLoaded();
214+
Object object = type.getConstructor().newInstance();
215+
type.getMethod("instrument").invoke(object);
216+
assertThat(type.getField("counter").get(object), is((Object) 1));
217+
}
218+
219+
@Test
220+
@JavaVersionRule.Enforce(24)
221+
public void testCanUseClassFileApiReaderOnly() throws Exception {
222+
Class<?> type = new ByteBuddy()
223+
.with(AsmClassReader.Factory.Default.CLASS_FILE_API_ONLY)
224+
.redefine(Recorder.class)
225+
.make()
226+
.load(ClassLoadingStrategy.BOOTSTRAP_LOADER, ClassLoadingStrategy.Default.WRAPPER)
227+
.getLoaded();
228+
Object object = type.getConstructor().newInstance();
229+
type.getMethod("instrument").invoke(object);
230+
assertThat(type.getField("counter").get(object), is((Object) 1));
231+
}
232+
233+
@Test
234+
@JavaVersionRule.Enforce(24)
235+
public void testCanUseClassFileApiWriterOnly() throws Exception {
236+
Class<?> type = new ByteBuddy()
237+
.with(AsmClassWriter.Factory.Default.CLASS_FILE_API_ONLY)
238+
.redefine(Recorder.class)
239+
.make()
240+
.load(ClassLoadingStrategy.BOOTSTRAP_LOADER, ClassLoadingStrategy.Default.WRAPPER)
241+
.getLoaded();
242+
Object object = type.getConstructor().newInstance();
243+
type.getMethod("instrument").invoke(object);
244+
assertThat(type.getField("counter").get(object), is((Object) 1));
245+
}
246+
202247
public static class Recorder {
203248

204249
public int counter;

0 commit comments

Comments
 (0)