Summary
AwsAgentBootstrap.premain appends the entire agent JAR to the bootstrap classloader search via inst.appendToBootstrapClassLoaderSearch(agentJar), and then delegates to OpenTelemetryAgent.agentmain → startAgent → installBootstrapJar, which appends the same whole JAR again. So the agent JAR ends up on the bootstrap search path twice, and in both cases it's the whole JAR (~1000+ root classes, including the upstream io.opentelemetry.javaagent.* launcher classes), even though only a small set of classes actually need to be bootstrap-visible.
The classes that genuinely need to be on the bootstrap classloader (so they're shared between ByteBuddy advice running in the application classloader and the collectors running in the agent classloader) are:
software.amazon.opentelemetry.javaagent.bootstrap.AwsInstrumentationHolder
- the
software.amazon.opentelemetry.javaagent.bootstrap.di.* bridge package
- the
software.amazon.opentelemetry.serviceevents.* bridge package
Why this is worth improving
This isn't an outright break on current JDKs, but it's a latent hazard and a minor regression:
- It defeats CDS / AppCDS. Each append emits
OpenJDK ... warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended, disabling class-data sharing (a startup-time/footprint cost) and printing a warning on stderr.
- The JDK
Instrumentation#appendToBootstrapClassLoaderSearch javadoc explicitly states the agent "should take care to ensure that the JAR does not contain any classes or resources other than those to be defined by the bootstrap class loader," warning that violating this can cause "unexpected behavior that is difficult to diagnose." Appending the whole agent JAR (which contains the upstream launcher/SDK classes, not just bootstrap-intended classes) — and doing so twice — works against that guidance and compounds boot-classpath mutation during the fragile startup window.
- The duplicate append is simply redundant work.
What is not the problem (so a fix can be scoped correctly)
These were checked empirically and are reassuring:
- It does not measurably increase memory or loaded-class count — a class is defined exactly once regardless of how many times the JAR is appended;
appendToBootstrapClassLoaderSearch only adds a search-path entry.
- It does not create duplicate
getResources() results for the application — boot-appended JAR resources do not surface through user-visible resource enumeration, so there's no ServiceLoader/SPI duplication.
- Removing the
premain append entirely is not a valid fix: AwsInstrumentationHolder then resolves as different copies in premain vs. the agent-classloader customizer, and the runtime feature that relies on the shared Instrumentation handle silently fails to initialize (getInstrumentation() returns null).
Suggested improvement
Append a minimal bootstrap JAR containing only AwsInstrumentationHolder + the two bridge packages, instead of the whole agent JAR — and avoid the redundant second append (or make it idempotent). This keeps the cross-classloader sharing intact, removes the duplicate append, aligns with the JDK guidance, and avoids unnecessarily disabling CDS.
Notes
Related to (but independent of) #1395, which addresses a separate Java 25 issue. This bootstrap-append item is lower priority — a future hardening/maintainability improvement, not a functional break on current JDKs.
Summary
AwsAgentBootstrap.premainappends the entire agent JAR to the bootstrap classloader search viainst.appendToBootstrapClassLoaderSearch(agentJar), and then delegates toOpenTelemetryAgent.agentmain→startAgent→installBootstrapJar, which appends the same whole JAR again. So the agent JAR ends up on the bootstrap search path twice, and in both cases it's the whole JAR (~1000+ root classes, including the upstreamio.opentelemetry.javaagent.*launcher classes), even though only a small set of classes actually need to be bootstrap-visible.The classes that genuinely need to be on the bootstrap classloader (so they're shared between ByteBuddy advice running in the application classloader and the collectors running in the agent classloader) are:
software.amazon.opentelemetry.javaagent.bootstrap.AwsInstrumentationHoldersoftware.amazon.opentelemetry.javaagent.bootstrap.di.*bridge packagesoftware.amazon.opentelemetry.serviceevents.*bridge packageWhy this is worth improving
This isn't an outright break on current JDKs, but it's a latent hazard and a minor regression:
OpenJDK ... warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended, disabling class-data sharing (a startup-time/footprint cost) and printing a warning on stderr.Instrumentation#appendToBootstrapClassLoaderSearchjavadoc explicitly states the agent "should take care to ensure that the JAR does not contain any classes or resources other than those to be defined by the bootstrap class loader," warning that violating this can cause "unexpected behavior that is difficult to diagnose." Appending the whole agent JAR (which contains the upstream launcher/SDK classes, not just bootstrap-intended classes) — and doing so twice — works against that guidance and compounds boot-classpath mutation during the fragile startup window.What is not the problem (so a fix can be scoped correctly)
These were checked empirically and are reassuring:
appendToBootstrapClassLoaderSearchonly adds a search-path entry.getResources()results for the application — boot-appended JAR resources do not surface through user-visible resource enumeration, so there's noServiceLoader/SPI duplication.premainappend entirely is not a valid fix:AwsInstrumentationHolderthen resolves as different copies inpremainvs. the agent-classloader customizer, and the runtime feature that relies on the sharedInstrumentationhandle silently fails to initialize (getInstrumentation()returns null).Suggested improvement
Append a minimal bootstrap JAR containing only
AwsInstrumentationHolder+ the two bridge packages, instead of the whole agent JAR — and avoid the redundant second append (or make it idempotent). This keeps the cross-classloader sharing intact, removes the duplicate append, aligns with the JDK guidance, and avoids unnecessarily disabling CDS.Notes
Related to (but independent of) #1395, which addresses a separate Java 25 issue. This bootstrap-append item is lower priority — a future hardening/maintainability improvement, not a functional break on current JDKs.