Comments (21)
Currently, you can use the MethodCall
instrumentation which is composable. For field access, there is no short cut way to do explicit instrumentations yet. Note that you need to call the super constructor in any constructor. It seems like you use a MethodConstant
where you probably want to invoke a constructor. This you can do via a MethodInvocation
in combination with a TypeCreation
.
from byte-buddy.
I would like to add the following code snippet to a class
public String traceId = ContextUtil.get(DidiContextEnum.TRACE_ID.name);
Can it be done?
@raphw
from byte-buddy.
You would need to define a field via defineField
and then set the field via any constructor. You can for example use Advice
to add this code to the end or beginning of each constructor.
from byte-buddy.
@raphw
First defineField,
then enhanced before and after the constructor is executed?
from byte-buddy.
I can't define fields and specify initialization code blocks? for example
new AgentBuilder.Default()
.type(named("com.Template"))
.transform((builder, typeDescription, classLoader, module) -> {
DynamicType.Builder.FieldDefinition.Optional.Valuable<?> name = builder.defineField("name", String.class, Modifier.PUBLIC);
// initialization code blocks. name = context.getname();
return name;
})
.installOn(inst);
from byte-buddy.
You can do both, but a non-static field must be initialized in a constructor.
For example, use Advice
as follows:
static void exit(@FieldValue(value = "name", readOnly = false) String name) {
name = ContextUtil.get(DidiContextEnum.TRACE_ID.name);
}
and then apply the visit method with Advice.to(MyAdvice.class).on(isConstructor())
.
from byte-buddy.
ByteBuddyAgent.install();
new ByteBuddy()
.redefine(Source.class)
.defineField("name", String.class, Modifier.PUBLIC)
.make()
.load(Source.class.getClassLoader());
Exception in thread "main" java.lang.IllegalStateException: Class already loaded: class com.example.a.Source
at net.bytebuddy.dynamic.loading.ByteArrayClassLoader.load(ByteArrayClassLoader.java:307)
at net.bytebuddy.dynamic.loading.ClassLoadingStrategy$Default$WrappingDispatcher.load(ClassLoadingStrategy.java:357)
at net.bytebuddy.dynamic.loading.ClassLoadingStrategy$Default.load(ClassLoadingStrategy.java:143)
at net.bytebuddy.dynamic.TypeResolutionStrategy$Passive.initialize(TypeResolutionStrategy.java:100)
at net.bytebuddy.dynamic.DynamicType$Default$Unloaded.load(DynamicType.java:5686)
at net.bytebuddy.dynamic.DynamicType$Default$Unloaded.load(DynamicType.java:5675)
at com.example.a.Main.main(Main.java:19)
from byte-buddy.
Do you want to add the field or create a new class? If you are doing the latter, you should rename the class. For the former, look into Java agents.
from byte-buddy.
I thought this would add fields to the original class
from byte-buddy.
Instrumentation install = ByteBuddyAgent.install();
new AgentBuilder.Default()
.type(ElementMatchers.is(Source.class))
.transform((builder, typeDescription, classLoader, javaModule) ->
builder.defineField("name", String.class, Modifier.PUBLIC))
.installOn(install);
Instrumentation install = ByteBuddyAgent.install();
new AgentBuilder.Default()
.type(ElementMatchers.named("com.example.a.Source"))
.transform((builder, typeDescription, classLoader, javaModule) ->
builder.defineField("name", String.class, Modifier.PUBLIC))
.installOn(install);
Don't these two codes do the same thing?@raphw
from byte-buddy.
Once you load a class via ElementMatchers.is(Source.class)
, its layout is set and the JVM does no longer allow adding fields to it.
You would need to add a matcher that does not load the class, for example via named("...")
. Additionally, you'd need to run this code before you load the class in other code.
from byte-buddy.
You can do both, but a non-static field must be initialized in a constructor.
For example, use
Advice
as follows:static void exit(@FieldValue(value = "name", readOnly = false) String name) { name = ContextUtil.get(DidiContextEnum.TRACE_ID.name); }
and then apply the visit method with
Advice.to(MyAdvice.class).on(isConstructor())
.
new AgentBuilder.Default() .type(ElementMatchers.named("com.example.a.Source")) .transform((builder, typeDescription, classLoader, javaModule) -> builder.defineField("name", String.class, Modifier.PUBLIC) .visit(Advice.to(MyAdvice.class).on(MethodDescription::isConstructor))) .installOn(install);
@raphw There is something wrong with this code
from byte-buddy.
Have you imported the correct @FieldValue
annotation? It needs to be the Advice
related one. You can register an AgentBuilder.Listener.StreamWriting.toSystemOut()
in the agent builder. Otherwise, you will not see any error messages.
from byte-buddy.
public class MyAdvice {
static void exit(@Advice.FieldValue(value = "name", readOnly = false) String name) {
name = "andre";
}
}
from byte-buddy.
@GetMapping
public Source test() {
return new Source();
}
before I add this code. Visit (Advice to (MyAdvice. Class.) on (MethodDescription: : isConstructor))
curl localhost. return {"id":null,"name":null}
add this code Visit (Advice to (MyAdvice. Class.) on (MethodDescription: : isConstructor))
curl localhost. return {"id":null}
@raphw
from byte-buddy.
What does your error log say? You can add it as I suggested.
from byte-buddy.
I didn't add @advice. OnMethodExit to the exit method,
java.lang.IllegalArgumentException: No advice defined by class
I can only initialize the name variable after the constructor, right?
@raphw
from byte-buddy.
You can write to fields in an enter advice if that's what you mean.
from byte-buddy.
@Advice.OnMethodEnter
static void exit( @Advice.FieldValue(value = "name", readOnly = false) String s) {
s = "andre";
}
java.lang.IllegalStateException: Cannot access non-static field before calling constructor: public com.example.a.Source()
from byte-buddy.
You are right. It's technically legal, but since reading is not allowed, it's fully forbidden. You would need to create your own offset mapping which does not have this restriction.
from byte-buddy.
thank you!@raphw
from byte-buddy.
Related Issues (20)
- 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
- defineField not working well HOT 1
- JDK class enhancements HOT 3
- ByteBuddy is incompatible with CDS due to the Java 6 baseline HOT 4
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.