Comments (4)
A lambda expression simply binds a value that is returned from a bootstrap method. If you want to bind a value, you should either intercept the constructor (members) or the initializer (static). From there, construct an expression and bind the result to the field. You could also use MethodDelegation
or Advice
to implement this code.
from byte-buddy.
Thanks for taking the time!
As far as I understand I do intercept the initializer and create an expression by using FieldAccessor.ofField("_writeObject").setsValue()
. If I change my added field to type String
and use setsValue("myString")
the field will be correctly initialized.
I only struggle to represent the method reference as the value.
I am not sure if MethodDelegation
could help, as I don't try to invoke ObjectOutputStream#defaultWriteObject
during initialization but assign the method reference instead. The docs also state
For invoking a method on another instance, use the MethodCall implementation
so I tried to assign a MethodCall
as value
// in MyPlugin.apply
builder = builder
.invokable(net.bytebuddy.matcher.ElementMatchers.isTypeInitializer())
.intercept(
net.bytebuddy.implementation.FieldAccessor.ofField("_writeObject").setsValue(
net.bytebuddy.implementation.MethodCall.of(
new net.bytebuddy.description.method.MethodDescription.ForLoadedMethod(
java.io.ObjectOutputStream.class.getMethod("defaultWriteObject"))
.withArgument(0)));
but it fails with the same exception as before.
from byte-buddy.
You will have to use InvokeDynamic#lambda
to bind a lambda expression (or method reference). Unfortunately, there is not yet a way to set the lambda expression as a field.
Instead, you can construct the lambda expression manually using MethodInvocation
by defining a manual call to LambdaMetaFactory
.
When using MethodCall
, you would also need to use the setsField
method from there.
from byte-buddy.
For future reference, if anyone has the same issue:
I tried to manually call the LambdaMetaFactory
which should in theory return a MethodHandle
that can be written to the byte code as a constant but ultimately got stuck on constructing the lambda correctly.
builder = builder.invokable(isTypeInitializer()).intercept(
FieldAccessor.ofField("_writeObject")
.setsValue(
// does not work :(
LambdaMetafactory.metafactory(
MethodHandles.lookup(),
"apply",
MethodType.methodType(WriteInterface.class, ObjectOutputStream.class),
MethodType.methodType(void.class, ObjectOutputStream.class),
MethodHandles.lookup().findVirtual(ObjectOutputStream.class, "defaultWriteObject", MethodType.methodType(void.class)),
MethodType.methodType(void.class)
).getTarget()));
I ended up creating another dynamic type to implement the functional interface and delegate the call to the target method (the "pre-java-8-way"). Then I call its default constructor to set my static field. This does not solve the original question/error but is sufficient in my use case.
// in MyPlugin.apply
DynamicType writeInterface = new net.bytebuddy.ByteBuddy()
.makeInterface()
.name("WriteInterface")
.defineMethod("apply", void.class, Visibility.PUBLIC)
.withParameter(ObjectOutputStream.class, "out")
.throwing(IOException.class)
.withoutCode()
.make();
DynamicType writeDefaultImpl = new ByteBuddy()
.subclass(Object.class)
.name("DefaultImpl")
.implement(writeInterface.getTypeDescription())
.defineMethod("apply", void.class, Visibility.PUBLIC)
.withParameter(ObjectOutputStream.class, "out")
.throwing(IOException.class)
.intercept(MethodCall.invoke(new MethodDescription.ForLoadedMethod(
ObjectOutputStream.class.getMethod("defaultWriteObject"))).onArgument(0))
.make();
builder = builder.require(writeInterface);
builder = builder.require(writeDefaultImpl);
builder = builder.defineField(
"_writeObject",
writeInterface.getTypeDescription(),
Visiblity.PUBLIC,
Ownership.STATIC);
builder = builder.invokable(isTypeInitializer()).intercept(
MethodCall.construct(writeDefaultImpl.getTypeDescription().getDeclaredMethods().filter(isDefaultConstructor()).getOnly())
.setsField(named("_writeObject")));
from byte-buddy.
Related Issues (20)
- AndroidClassLoadingStrategy Injecting problem in Android SDK 33 HOT 3
- [maven plugin] transform-extended does not include dependency classes HOT 14
- latest guava cause [ unexpected type reference on method: 16 ] HOT 5
- `MemberSubstitution` can't replace instructions within synthetic methods. HOT 2
- IllegalArgumentException for Kotlin bytecode with erased type argument HOT 9
- Can byte-buddy modify bytecode in parallel? HOT 4
- Java 17 reflection changes
- A lazy `TypePool` will change with type resolution and thus deviate from its initial configuration. HOT 2
- JDK 23 Valhalla-EA: IllegalState Illegal modifiers 33 for class HOT 2
- Multiple transformation issue with JMH benchmarks HOT 1
- [question] How can replace field access with another class? HOT 2
- Eclipse project compilation error using mockito and byte-buddy HOT 5
- Runtime attachment causing VerifyError during class transformation HOT 8
- not able to intercept java.lang package HOT 9
- Questions about alternatives to the LocalVariablesSorter class obsoletization HOT 1
- How to create a class with updated private field using ByteBuddy? HOT 2
- Byte buddy access to package protected class HOT 4
- mockito-android:5.12.0 cannot mock class HOT 1
- How to invoke the method of injecting objects into a class? HOT 2
- [Question] Why would a new field var2 be added after replace field access with method? 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.