1313import  static  java .util .logging .Level .FINE ;
1414import  static  java .util .logging .Level .SEVERE ;
1515import  static  net .bytebuddy .matcher .ElementMatchers .any ;
16+ import  static  net .bytebuddy .matcher .ElementMatchers .none ;
1617
1718import  io .opentelemetry .context .Context ;
1819import  io .opentelemetry .context .ContextStorage ;
3031import  io .opentelemetry .javaagent .bootstrap .internal .ConfiguredResourceAttributesHolder ;
3132import  io .opentelemetry .javaagent .extension .AgentListener ;
3233import  io .opentelemetry .javaagent .extension .ignore .IgnoredTypesConfigurer ;
34+ import  io .opentelemetry .javaagent .extension .instrumentation .internal .EarlyInstrumentationModule ;
3335import  io .opentelemetry .javaagent .tooling .asyncannotationsupport .WeakRefAsyncOperationEndStrategies ;
3436import  io .opentelemetry .javaagent .tooling .bootstrap .BootstrapPackagesBuilderImpl ;
3537import  io .opentelemetry .javaagent .tooling .bootstrap .BootstrapPackagesConfigurer ;
3638import  io .opentelemetry .javaagent .tooling .config .ConfigPropertiesBridge ;
3739import  io .opentelemetry .javaagent .tooling .config .EarlyInitAgentConfig ;
40+ import  io .opentelemetry .javaagent .tooling .field .FieldBackedImplementationConfiguration ;
41+ import  io .opentelemetry .javaagent .tooling .field .VirtualFieldImplementationInstaller ;
42+ import  io .opentelemetry .javaagent .tooling .field .VirtualFieldImplementationInstallerFactory ;
3843import  io .opentelemetry .javaagent .tooling .ignore .IgnoredClassLoadersMatcher ;
3944import  io .opentelemetry .javaagent .tooling .ignore .IgnoredTypesBuilderImpl ;
4045import  io .opentelemetry .javaagent .tooling .ignore .IgnoredTypesMatcher ;
4954import  java .util .HashMap ;
5055import  java .util .List ;
5156import  java .util .Map ;
57+ import  java .util .Objects ;
5258import  java .util .logging .LogManager ;
5359import  java .util .logging .Logger ;
5460import  java .util .stream .Stream ;
@@ -84,6 +90,8 @@ public class AgentInstaller {
8490
8591  private  static  final  Map <String , List <Runnable >> CLASS_LOAD_CALLBACKS  = new  HashMap <>();
8692
93+   private  static  volatile  boolean  instrumentationInstalled ;
94+ 
8795  public  static  void  installBytebuddyAgent (
8896      Instrumentation  inst , ClassLoader  extensionClassLoader , EarlyInitAgentConfig  earlyConfig ) {
8997    addByteBuddyRawSetting ();
@@ -98,7 +106,7 @@ public static void installBytebuddyAgent(
98106    if  (earlyConfig .getBoolean (JAVAAGENT_ENABLED_CONFIG , true )) {
99107      setupUnsafe (inst );
100108      List <AgentListener > agentListeners  = loadOrdered (AgentListener .class , extensionClassLoader );
101-       installBytebuddyAgent (inst , extensionClassLoader , agentListeners );
109+       installBytebuddyAgent (inst , extensionClassLoader , agentListeners ,  earlyConfig );
102110    } else  {
103111      logger .fine ("Tracing is disabled, not installing instrumentations." );
104112    }
@@ -107,31 +115,13 @@ public static void installBytebuddyAgent(
107115  private  static  void  installBytebuddyAgent (
108116      Instrumentation  inst ,
109117      ClassLoader  extensionClassLoader ,
110-       Iterable <AgentListener > agentListeners ) {
118+       Iterable <AgentListener > agentListeners ,
119+       EarlyInitAgentConfig  earlyConfig ) {
111120
112121    WeakRefAsyncOperationEndStrategies .initialize ();
113- 
114122    EmbeddedInstrumentationProperties .setPropertiesLoader (extensionClassLoader );
115- 
116123    setDefineClassHandler ();
117- 
118-     // If noop OpenTelemetry is enabled, autoConfiguredSdk will be null and AgentListeners are not 
119-     // called 
120-     AutoConfiguredOpenTelemetrySdk  autoConfiguredSdk  =
121-         installOpenTelemetrySdk (extensionClassLoader );
122- 
123-     ConfigProperties  sdkConfig  = AgentListener .resolveConfigProperties (autoConfiguredSdk );
124-     AgentInstrumentationConfig .internalInitializeConfig (new  ConfigPropertiesBridge (sdkConfig ));
125-     copyNecessaryConfigToSystemProperties (sdkConfig );
126- 
127-     setBootstrapPackages (sdkConfig , extensionClassLoader );
128-     ConfiguredResourceAttributesHolder .initialize (
129-         SdkAutoconfigureAccess .getResourceAttributes (autoConfiguredSdk ));
130- 
131-     for  (BeforeAgentListener  agentListener  :
132-         loadOrdered (BeforeAgentListener .class , extensionClassLoader )) {
133-       agentListener .beforeAgent (autoConfiguredSdk );
134-     }
124+     FieldBackedImplementationConfiguration .configure (earlyConfig );
135125
136126    AgentBuilder  agentBuilder  =
137127        new  AgentBuilder .Default (
@@ -153,9 +143,6 @@ private static void installBytebuddyAgent(
153143    if  (JavaModule .isSupported ()) {
154144      agentBuilder  = agentBuilder .with (new  ExposeAgentBootstrapListener (inst ));
155145    }
156- 
157-     agentBuilder  = configureIgnoredTypes (sdkConfig , extensionClassLoader , agentBuilder );
158- 
159146    if  (logger .isLoggable (FINE )) {
160147      agentBuilder  =
161148          agentBuilder 
@@ -165,6 +152,28 @@ private static void installBytebuddyAgent(
165152              .with (new  TransformLoggingListener ());
166153    }
167154
155+     installEarlyInstrumentation (agentBuilder , inst );
156+ 
157+     // If noop OpenTelemetry is enabled, autoConfiguredSdk will be null and AgentListeners are not 
158+     // called 
159+     AutoConfiguredOpenTelemetrySdk  autoConfiguredSdk  =
160+         installOpenTelemetrySdk (extensionClassLoader );
161+ 
162+     ConfigProperties  sdkConfig  = AgentListener .resolveConfigProperties (autoConfiguredSdk );
163+     AgentInstrumentationConfig .internalInitializeConfig (new  ConfigPropertiesBridge (sdkConfig ));
164+     copyNecessaryConfigToSystemProperties (sdkConfig );
165+ 
166+     setBootstrapPackages (sdkConfig , extensionClassLoader );
167+     ConfiguredResourceAttributesHolder .initialize (
168+         SdkAutoconfigureAccess .getResourceAttributes (autoConfiguredSdk ));
169+ 
170+     for  (BeforeAgentListener  agentListener  :
171+         loadOrdered (BeforeAgentListener .class , extensionClassLoader )) {
172+       agentListener .beforeAgent (autoConfiguredSdk );
173+     }
174+ 
175+     agentBuilder  = configureIgnoredTypes (sdkConfig , extensionClassLoader , agentBuilder );
176+ 
168177    int  numberOfLoadedExtensions  = 0 ;
169178    for  (AgentExtension  agentExtension  : loadOrdered (AgentExtension .class , extensionClassLoader )) {
170179      if  (logger .isLoggable (FINE )) {
@@ -191,13 +200,44 @@ private static void installBytebuddyAgent(
191200
192201    agentBuilder  = AgentBuilderUtil .optimize (agentBuilder );
193202    ResettableClassFileTransformer  resettableClassFileTransformer  = agentBuilder .installOn (inst );
203+     instrumentationInstalled  = true ;
194204    ClassFileTransformerHolder .setClassFileTransformer (resettableClassFileTransformer );
195205
196206    addHttpServerResponseCustomizers (extensionClassLoader );
197207
198208    runAfterAgentListeners (agentListeners , autoConfiguredSdk , sdkConfig );
199209  }
200210
211+   private  static  void  installEarlyInstrumentation (
212+       AgentBuilder  agentBuilder , Instrumentation  instrumentation ) {
213+     // We are only going to install the virtual fields here. Installing virtual field changes class 
214+     // structure and can not be applied to already loaded classes. 
215+     agentBuilder  = agentBuilder .with (AgentBuilder .RedefinitionStrategy .DISABLED );
216+ 
217+     AgentBuilder .Identified .Extendable  extendableAgentBuilder  =
218+         agentBuilder 
219+             .ignore (
220+                 target  -> instrumentationInstalled , // turn off after instrumentation is installed 
221+                 Objects ::nonNull )
222+             .type (none ())
223+             .transform (
224+                 (builder , typeDescription , classLoader , module , protectionDomain ) -> builder );
225+ 
226+     VirtualFieldImplementationInstallerFactory  virtualFieldInstallerFactory  =
227+         new  VirtualFieldImplementationInstallerFactory ();
228+     for  (EarlyInstrumentationModule  earlyInstrumentationModule  :
229+         loadOrdered (EarlyInstrumentationModule .class , Utils .getExtensionsClassLoader ())) {
230+ 
231+       VirtualFieldImplementationInstaller  contextProvider  =
232+           virtualFieldInstallerFactory .create (
233+               earlyInstrumentationModule .getInstrumentationModule ());
234+       extendableAgentBuilder  = contextProvider .injectFields (extendableAgentBuilder );
235+     }
236+ 
237+     agentBuilder  = AgentBuilderUtil .optimize (extendableAgentBuilder );
238+     agentBuilder .installOn (instrumentation );
239+   }
240+ 
201241  private  static  void  copyNecessaryConfigToSystemProperties (ConfigProperties  config ) {
202242    for  (String  property  : asList ("otel.instrumentation.experimental.span-suppression-strategy" )) {
203243      String  value  = config .getString (property );
0 commit comments