Comments (3)
This is absolutely possible. In general, you are able to create any possible Java class by using the exposed ASM-API. However, for your example, you can even use the ASM wrapper classes that already ship with Byte Buddy to implement this.
Please see my answer on StackOverflow (http://stackoverflow.com/questions/24711172/how-in-java-to-assign-to-fields-with-byte-buddy/24735122#24735122) for how to implement this with Byte Buddy.
from byte-buddy.
Thanks!
That I can tell I am unable to create new methods, only to
override/implement existing methods. For example I tried making an "a()"
method to access the "a" field on a class extending Object, and discovered
the "a()" method is always not found.
package lab.bytegen;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.instrumentation.Instrumentation;
import net.bytebuddy.instrumentation.Instrumentation.Context;
import net.bytebuddy.instrumentation.Instrumentation.Target;
import net.bytebuddy.instrumentation.method.MethodDescription;
import net.bytebuddy.instrumentation.method.bytecode.ByteCodeAppender;
import net.bytebuddy.instrumentation.method.bytecode.stack.StackManipulation;
import net.bytebuddy.instrumentation.method.bytecode.stack.member.FieldAccess;
import net.bytebuddy.instrumentation.method.bytecode.stack.member.MethodInvocation;
import net.bytebuddy.instrumentation.method.bytecode.stack.member.MethodReturn;
import net.bytebuddy.instrumentation.type.InstrumentedType;
import net.bytebuddy.instrumentation.type.TypeDescription;
import net.bytebuddy.jar.asm.MethodVisitor;
import net.bytebuddy.modifier.FieldManifestation;
import net.bytebuddy.modifier.TypeManifestation;
import java.lang.reflect.Field;
import java.util.Arrays;
import static java.lang.System.out;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static net.bytebuddy.ClassFileVersion.JAVA_V8;
import static net.bytebuddy.dynamic.ClassLoadingStrategy.Default.INJECTION;
import static net.bytebuddy.dynamic.scaffold.subclass.ConstructorStrategy.Default.NO_CONSTRUCTORS;
import static net.bytebuddy.instrumentation.method.bytecode.stack.member.MethodVariableAccess
.INTEGER;
import static net.bytebuddy.instrumentation.method.bytecode.stack.member.MethodVariableAccess
.REFERENCE;
import static net.bytebuddy.instrumentation.method.matcher.MethodMatchers.isConstructor;
import static net.bytebuddy.instrumentation.method.matcher.MethodMatchers.isMethod;
import static net.bytebuddy.instrumentation.method.matcher.MethodMatchers.named;
import static net.bytebuddy.instrumentation.method.matcher.MethodMatchers.returns;
import static net.bytebuddy.instrumentation.method.matcher.MethodMatchers.takesArguments;
import static net.bytebuddy.modifier.Visibility.PRIVATE;
import static net.bytebuddy.modifier.Visibility.PUBLIC;
/**
-
{@code WriteAClassMain} needs documentation.
* -
@see <a href="http://stackoverflow.com/questions/24711172/how-in-java-to-assign-to-fields-with
-
-byte-buddy">How in Java to assign to fields with Byte Buddy?
*/
public final class WriteAClassMain {public static void main(final String... args)
throws Exception {final Class<?> aClass = new ByteBuddy(). subclass(Object.class, NO_CONSTRUCTORS). classFileVersion(JAVA_V8). modifiers(PUBLIC, TypeManifestation.FINAL). name("foo.AClass"). defineField("a", int.class, PRIVATE, FieldManifestation.FINAL). defineConstructor(singletonList(int.class), PUBLIC). intercept(new IntFieldInterceptor("a", IntFieldPutter::new)). defineMethod("a", int.class, emptyList(), PUBLIC). intercept(new IntFieldInterceptor("a", IntFieldGetter::new)). make(). // saveIn(File file). load(WriteAClassMain.class.getClassLoader(), INJECTION). getLoaded(); final Object o = aClass. getConstructor(int.class). newInstance(3); out.println(Arrays.toString(aClass.getDeclaredFields())); out.println(Arrays.toString(aClass.getDeclaredConstructors())); out.println(Arrays.toString(aClass.getDeclaredMethods())); final Field a = aClass.getDeclaredField("a"); a.setAccessible(true); out.println(a.get(o));
}
private interface I {
ByteCodeAppender i(final Target instrumentationTarget, final
String name);
}private static final class IntFieldInterceptor
implements Instrumentation {private final String name; private final I i; IntFieldInterceptor(final String name, I i) { this.name = name; this.i = i; } @Override public InstrumentedType prepare(final InstrumentedType
instrumentedType) {
return instrumentedType; } @Override public ByteCodeAppender appender(final Target instrumentationTarget) { return i.i(instrumentationTarget, name); }
}
private static final class IntFieldPutter
implements ByteCodeAppender {private final Target instrumentationTarget; private final String name; IntFieldPutter(final Target instrumentationTarget, final String name) { this.instrumentationTarget = instrumentationTarget; this.name = name; } @Override public boolean appendsCode() { return true; } @Override public Size apply(final MethodVisitor methodVisitor, final
Context instrumentationContext,
final MethodDescription instrumentedMethod) {
final StackManipulation arg0 = REFERENCE.loadFromIndex(0);
final StackManipulation iArg1 = INTEGER.loadFromIndex(1);
final StackManipulation.Size size = new
StackManipulation.Compound(arg0,
MethodInvocation.invoke(new
TypeDescription.ForLoadedType(Object.class).getDeclaredMethods(). filter(isConstructor(). and(takesArguments(0))). getOnly()), arg0, iArg1,
FieldAccess.forField(instrumentationTarget.
getTypeDescription(). getDeclaredFields(). named(name)). putter(), MethodReturn.VOID). apply(methodVisitor, instrumentationContext); return new Size(size.getMaximalSize(),
instrumentedMethod.getStackSize());
}
}private static final class IntFieldGetter
implements ByteCodeAppender {private final Target instrumentationTarget; private final String name; IntFieldGetter(final Target instrumentationTarget, final String name) { this.instrumentationTarget = instrumentationTarget; this.name = name; } @Override public boolean appendsCode() { return true; } @Override public Size apply(final MethodVisitor methodVisitor, final
Context instrumentationContext,
final MethodDescription instrumentedMethod) {
final StackManipulation arg0 = REFERENCE.loadFromIndex(0);
final StackManipulation.Size size = new
StackManipulation.Compound(arg0,
MethodInvocation.invoke(new
TypeDescription.ForLoadedType(Object.class).getDeclaredMethods(). // TODO: No such method in Object filter(isMethod(). and(named(name)). and(takesArguments(0)). and(returns(int.class))). getOnly()), arg0,
FieldAccess.forField(instrumentationTarget.
getTypeDescription(). getDeclaredFields(). named(name)). getter(), MethodReturn.INTEGER). apply(methodVisitor, instrumentationContext); return new Size(size.getMaximalSize(),
instrumentedMethod.getStackSize());
}
}
}
Cheers,
--binkley
On Fri, Jul 18, 2014 at 6:03 PM, Rafael Winterhalter <
[email protected]> wrote:
This is absolutely possible. In general, you are able to create any
possible Java class by using the exposed ASM-API. However, for your
example, you can even use the ASM wrapper classes that already ship with
Byte Buddy to implement this.Please see my answer on StackOverflow (
http://stackoverflow.com/questions/24711172/how-in-java-to-assign-to-fields-with-byte-buddy/24735122#24735122)
for how to implement this with Byte Buddy.—
Reply to this email directly or view it on GitHub
#3 (comment).
from byte-buddy.
It looks like you are trying to find a method named a
in the Object
class:
TypeDescription.ForLoadedType(Object.class)
.getDeclaredMethods()
.filter(isMethod(). and(named(name)). and(takesArguments(0)). and(returns(int.class)))
.getOnly();
The Object
class does however not define any method named a
. Rather check instrumentationTarget.getTypeDescription()
for the method which you defined for your newly defined type (the instrumentation target's type).
from byte-buddy.
Related Issues (20)
- byte-buddy J9 attachment only checks for self-owned directories HOT 14
- Why doesn't this simple example work? HOT 5
- Can ByteBuddy add synchronized to intercepted setters? HOT 2
- Can ByteBuddy make a non-static field be final? HOT 1
- seems that namedOneOf isn't working as expected HOT 1
- Release missing of version 1.14.15 HOT 1
- java.lang.NoSuchMethodError when using the agent for method instrumentation HOT 2
- Cannot invoke public constructor HOT 5
- ByteBuddyAgent, Java 21 - A Java agent has been loaded dynamically HOT 2
- include method does not exist for Method Delegation approach HOT 6
- Having trouble delegating added instance method to static method HOT 2
- Setting value in constructor aliases collections HOT 5
- Is it possible to lazily instantiate AllArguments?
- install transformer takes too long time HOT 3
- Example that could be used in documentation HOT 6
- Issues attaching to Solaris Hotspot on Solaris 10 and 11. HOT 1
- How to generate multi-level generic code ? HOT 2
- java.lang.IllegalAccessError HOT 15
- InjectionStrategy.UsingUnsafe.OfFactory HOT 1
- java.lang.IncompatibleClassChangeError: Interface method reference: java.util.stream.Sink.begin(J)V HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from byte-buddy.