Skip to content

Commit

Permalink
Add tests for patching class file version
Browse files Browse the repository at this point in the history
Some are currently failing
see raphw/byte-buddy#880
  • Loading branch information
felixbarny committed Jun 14, 2020
1 parent 98d5fb0 commit 019ad45
Show file tree
Hide file tree
Showing 8 changed files with 335 additions and 39 deletions.
12 changes: 12 additions & 0 deletions apm-agent-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,18 @@
<version>${version.cucumber}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math3</artifactId>
<version>3.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.6.2</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -451,9 +451,11 @@ public static synchronized void reset() {
}
dynamicClassFileTransformers.clear();
instrumentation = null;
HelperClassManager.ForIndyPlugin.clear();
}

private static AgentBuilder getAgentBuilder(final ByteBuddy byteBuddy, final CoreConfiguration coreConfiguration, Logger logger, AgentBuilder.DescriptionStrategy descriptionStrategy, boolean premain) {
private static AgentBuilder getAgentBuilder(final ByteBuddy byteBuddy, final CoreConfiguration coreConfiguration, final Logger logger,
final AgentBuilder.DescriptionStrategy descriptionStrategy, final boolean premain) {
AgentBuilder.LocationStrategy locationStrategy = AgentBuilder.LocationStrategy.ForClassLoader.WEAK;
if (agentJarFile != null) {
try {
Expand All @@ -475,6 +477,14 @@ private static AgentBuilder getAgentBuilder(final ByteBuddy byteBuddy, final Cor
// when runtime attaching, only retransform up to 100 classes at once and sleep 100ms in-between as retransformation causes a stop-the-world pause
.with(premain ? RedefinitionStrategy.BatchAllocator.ForTotal.INSTANCE : RedefinitionStrategy.BatchAllocator.ForFixedSize.ofSize(100))
.with(premain ? RedefinitionStrategy.Listener.NoOp.INSTANCE : RedefinitionStrategy.Listener.Pausing.of(100, TimeUnit.MILLISECONDS))
.with(new RedefinitionStrategy.Listener.Adapter() {
@Override
public Iterable<? extends List<Class<?>>> onError(int index, List<Class<?>> batch, Throwable throwable, List<Class<?>> types) {
logger.warn("Error while redefining classes {}", throwable.getMessage());
logger.debug(throwable.getMessage(), throwable);
return super.onError(index, batch, throwable, types);
}
})
.with(descriptionStrategy)
.with(locationStrategy)
.with(new ErrorLoggingListener())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -284,13 +284,17 @@ public static class ForIndyPlugin {
* Creates an isolated CL that has two parents: the target class loader and the agent CL.
* The agent class loader is currently the bootstrap CL but in the future it will be an isolated CL that is a child of the bootstrap CL.
*/
@Nullable
public synchronized static ClassLoader getOrCreatePluginClassLoader(@Nullable ClassLoader targetClassLoader, @Nullable ProtectionDomain protectionDomain, List<String> classesToInject, ElementMatcher<? super TypeDescription> exclusionMatcher) throws Exception {
public synchronized static ClassLoader getOrCreatePluginClassLoader(@Nullable ClassLoader targetClassLoader, List<String> classesToInject, ElementMatcher<? super TypeDescription> exclusionMatcher) throws Exception {
classesToInject = new ArrayList<>(classesToInject);

Map<Collection<String>, WeakReference<ClassLoader>> injectedClasses = getOrCreateInjectedClasses(targetClassLoader);
if (injectedClasses.containsKey(classesToInject)) {
return injectedClasses.get(classesToInject).get();
ClassLoader pluginClassLoader = injectedClasses.get(classesToInject).get();
if (pluginClassLoader == null) {
injectedClasses.remove(classesToInject);
} else {
return pluginClassLoader;
}
}

List<String> classesToInjectCopy = new ArrayList<>(classesToInject.size());
Expand All @@ -309,7 +313,6 @@ public synchronized static ClassLoader getOrCreatePluginClassLoader(@Nullable Cl
ClassLoader pluginClassLoader = new ByteArrayClassLoader.ChildFirst(parent, true, typeDefinitions, ByteArrayClassLoader.PersistenceHandler.MANIFEST);
injectedClasses.put(classesToInject, new WeakReference<>(pluginClassLoader));


return pluginClassLoader;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,14 +236,10 @@ public static ConstantCallSite bootstrap(MethodHandles.Lookup lookup,
}
ClassLoader pluginClassLoader = HelperClassManager.ForIndyPlugin.getOrCreatePluginClassLoader(
lookup.lookupClass().getClassLoader(),
instrumentedType.getProtectionDomain(),
pluginClasses,
isAnnotatedWith(named(GlobalState.class.getName())));
if (pluginClassLoader != null) {
Class<?> adviceInPluginCL = pluginClassLoader.loadClass(adviceClassName);
MethodHandle methodHandle = MethodHandles.lookup().findStatic(adviceInPluginCL, adviceMethodName, adviceMethodType);
return new ConstantCallSite(methodHandle);
}
return null;
Class<?> adviceInPluginCL = pluginClassLoader.loadClass(adviceClassName);
MethodHandle methodHandle = MethodHandles.lookup().findStatic(adviceInPluginCL, adviceMethodName, adviceMethodType);
return new ConstantCallSite(methodHandle);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,7 @@ public static List<String> getClassNames(final String basePackage) throws IOExce
}
}
} else {
final Path basePath = Paths.get(uri);
if (basePath.toString().contains("test-classes")) {
continue;
}
classNames.addAll(listClassNames(basePackage, basePath));
classNames.addAll(listClassNames(basePackage, Paths.get(uri)));
}
}
return classNames;
Expand Down
Loading

0 comments on commit 019ad45

Please sign in to comment.