Add documentation about java agent structure and related classloaders (#380)
This commit is contained in:
parent
f964725d96
commit
67766fd13b
|
@ -8,6 +8,53 @@ In order to fully build and test this whole repository you need the following:
|
||||||
* Java 8 should be set as default: `java -version` should give you version 8.
|
* Java 8 should be set as default: `java -version` should give you version 8.
|
||||||
* Defined environment variables `JAVA_8_HOME` and `JAVA_9_HOME` which point to the corresponding java homes.
|
* Defined environment variables `JAVA_8_HOME` and `JAVA_9_HOME` which point to the corresponding java homes.
|
||||||
|
|
||||||
|
### Plugin structure
|
||||||
|
OpenTelemetry Auto Instrumentation java agent's jar can logically be divided into 3 parts.
|
||||||
|
|
||||||
|
#### `java-agent` module
|
||||||
|
This module consists of single class `io.opentelemetry.auto.bootstrap.AgentBootstrap`
|
||||||
|
which implements [Java instrumentation agent](https://docs.oracle.com/javase/7/docs/api/java/lang/instrument/package-summary.html).
|
||||||
|
This class is loaded during application startup by application classloader.
|
||||||
|
Its sole responsibility is to push agent's classes into JVM's bootstrap classloader
|
||||||
|
and immediately delegate to `io.opentelemetry.auto.bootstrap.Agent` (now in the bootstrap class loader) class from there.
|
||||||
|
|
||||||
|
#### `agent-bootstrap` module
|
||||||
|
This module contains support classes for actual instrumentations to be loaded later and separately.
|
||||||
|
These classes should be available from all possible classloaders in the running application.
|
||||||
|
For this reason `java-agent` puts all these classes into JVM's bootstrap classloader.
|
||||||
|
For the same reason this module should be as small as possible and have as few dependencies as possible.
|
||||||
|
Otherwise, there is a risk of accidentally exposing this classes to the actual application.
|
||||||
|
|
||||||
|
#### `agent-tooling` module and `instrumentation` submodules
|
||||||
|
Contains everything necessary to make instrumentation machinery work,
|
||||||
|
including integration with [ByteBuddy](https://bytebuddy.net/) and actual library-specific instrumentations.
|
||||||
|
As these classes depend on many classes from different libraries,
|
||||||
|
it is paramount to hide all these classes from the host application.
|
||||||
|
This is achieved in the following way:
|
||||||
|
* When `java-agent` module builds the final agent, it moves all classes from `instrumentation` submodules
|
||||||
|
and `agent-tooling` module into a separate folder inside final jar file, called `auto-tooling-and-instrumentation.isolated`.
|
||||||
|
In addition, the extension of all class files is changed from `class` to `classdata`.
|
||||||
|
This ensures that general classloaders cannot find nor load these classes.
|
||||||
|
* When `io.opentelemetry.auto.bootstrap.Agent` starts up,
|
||||||
|
it creates an instance of `io.opentelemetry.auto.bootstrap.AgentClassLoader`,
|
||||||
|
loads an `io.opentelemetry.auto.tooling.AgentInstaller` from that `AgentClassLoader`
|
||||||
|
and then passes control on to the `AgentInstaller` (now in the `AgentClassLoader`). The `AgentInstaller` then installs all of the instrumentations with the help of ByteBuddy.
|
||||||
|
|
||||||
|
The complicated process above ensures that the majority of auto-instrumentation agent's classes
|
||||||
|
are totally isolated from application classes,
|
||||||
|
and an instrumented class from arbitrary classloader in JVM can still access helper classes from bootstrap classloader.
|
||||||
|
|
||||||
|
#### Agent jar structure
|
||||||
|
If you now look inside `java-agent/build/libs/opentelemetry-auto-<version>.jar`,
|
||||||
|
you will see the following "clusters" of classes:
|
||||||
|
* `auto-tooling-and-instrumentation.isolated/` - contains `agent-tooling` module and
|
||||||
|
`instrumentation` submodules, loaded and isolated inside `AgentClassLoader`.
|
||||||
|
Including OpenTelemetry SDK.
|
||||||
|
* `io/opentelemetry/auto/bootstrap/` - contains `agent-bootstrap` module and available in
|
||||||
|
bootstrap classloader.
|
||||||
|
* `io/opentelemetry/auto/shaded/` - contains OpenTelemetry API and its dependencies.
|
||||||
|
Shaded during creation of `java-agent` jar file by Shadow Gradle plugin.
|
||||||
|
|
||||||
### Testing
|
### Testing
|
||||||
#### Java versions
|
#### Java versions
|
||||||
Open Telemetry Auto Instrumentation's minimal supported version is java 7.
|
Open Telemetry Auto Instrumentation's minimal supported version is java 7.
|
||||||
|
|
|
@ -197,12 +197,11 @@ public class Agent {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create the agent classloader. This must be called after the bootstrap jar has been appened to
|
* Create the agent classloader. This must be called after the bootstrap jar has been appended to
|
||||||
* the bootstrap classpath.
|
* the bootstrap classpath.
|
||||||
*
|
*
|
||||||
* @param innerJarFilename Filename of internal jar to use for the classpath of the agent
|
* @param innerJarFilename Filename of internal jar to use for the classpath of the agent
|
||||||
* classloader
|
* classloader
|
||||||
* @param bootstrapURL
|
|
||||||
* @return Agent Classloader
|
* @return Agent Classloader
|
||||||
*/
|
*/
|
||||||
private static ClassLoader createAgentClassLoader(
|
private static ClassLoader createAgentClassLoader(
|
||||||
|
|
Loading…
Reference in New Issue