Skip to content

Commit

Permalink
Refactored Byte Buddy agent installation to support the new Java 9 la…
Browse files Browse the repository at this point in the history
…yout for Jigsaw and for allowing divering locations for tools.jar (e.g. Mac JVMs and IBM J9). Furthermore, allowed for custom localization for supporting user-located attachments for more exotic VMs.
  • Loading branch information
Rafael Winterhalter committed Sep 16, 2015
1 parent eaf8232 commit 1666d0d
Show file tree
Hide file tree
Showing 9 changed files with 855 additions and 77 deletions.
493 changes: 435 additions & 58 deletions byte-buddy-agent/src/main/java/net/bytebuddy/agent/ByteBuddyAgent.java

Large diffs are not rendered by default.

Expand Up @@ -10,14 +10,14 @@
import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;


public class ByteBuddyAgentOpenJdkTest { public class ByteBuddyAgentInstallationTest {


@Rule @Rule
public MethodRule toolsJarRule = new ToolsJarRule(); public MethodRule toolsJarRule = new ToolsJarRule();


@Test @Test
@ToolsJarRule.Enforce @ToolsJarRule.Enforce
public void testAgentInstallation() throws Exception { public void testAgentInstallation() throws Exception {
assertThat(ByteBuddyAgent.installOnOpenJDK(), instanceOf(Instrumentation.class)); assertThat(ByteBuddyAgent.install(), instanceOf(Instrumentation.class));
} }
} }

Large diffs are not rendered by default.

Expand Up @@ -135,7 +135,7 @@ public void testTutorialGettingStartedClassLoading() throws Exception {
@Test @Test
@ToolsJarRule.Enforce @ToolsJarRule.Enforce
public void testTutorialGettingStartedClassReloading() throws Exception { public void testTutorialGettingStartedClassReloading() throws Exception {
ByteBuddyAgent.installOnOpenJDK(); ByteBuddyAgent.install();
FooReloading foo = new FooReloading(); FooReloading foo = new FooReloading();
new ByteBuddy() new ByteBuddy()
.redefine(BarReloading.class) .redefine(BarReloading.class)
Expand Down
Expand Up @@ -54,7 +54,7 @@ public void setUp() throws Exception {
@Test @Test
@ToolsJarRule.Enforce @ToolsJarRule.Enforce
public void testAgentWithoutSelfInitialization() throws Exception { public void testAgentWithoutSelfInitialization() throws Exception {
assertThat(ByteBuddyAgent.installOnOpenJDK(), instanceOf(Instrumentation.class)); assertThat(ByteBuddyAgent.install(), instanceOf(Instrumentation.class));
ClassFileTransformer classFileTransformer = new AgentBuilder.Default() ClassFileTransformer classFileTransformer = new AgentBuilder.Default()
.disableSelfInitialization() .disableSelfInitialization()
.rebase(isAnnotatedWith(ShouldRebase.class), ElementMatchers.is(classLoader)).transform(new FooTransformer()) .rebase(isAnnotatedWith(ShouldRebase.class), ElementMatchers.is(classLoader)).transform(new FooTransformer())
Expand All @@ -70,7 +70,7 @@ public void testAgentWithoutSelfInitialization() throws Exception {
@Test @Test
@ToolsJarRule.Enforce @ToolsJarRule.Enforce
public void testAgentSelfInitialization() throws Exception { public void testAgentSelfInitialization() throws Exception {
assertThat(ByteBuddyAgent.installOnOpenJDK(), instanceOf(Instrumentation.class)); assertThat(ByteBuddyAgent.install(), instanceOf(Instrumentation.class));
ClassFileTransformer classFileTransformer = new AgentBuilder.Default() ClassFileTransformer classFileTransformer = new AgentBuilder.Default()
.rebase(isAnnotatedWith(ShouldRebase.class), ElementMatchers.is(classLoader)).transform(new BarTransformer()) .rebase(isAnnotatedWith(ShouldRebase.class), ElementMatchers.is(classLoader)).transform(new BarTransformer())
.installOnByteBuddyAgent(); .installOnByteBuddyAgent();
Expand All @@ -85,7 +85,7 @@ public void testAgentSelfInitialization() throws Exception {
@Test @Test
@ToolsJarRule.Enforce @ToolsJarRule.Enforce
public void testAgentSelfInitializationAuxiliaryTypes() throws Exception { public void testAgentSelfInitializationAuxiliaryTypes() throws Exception {
assertThat(ByteBuddyAgent.installOnOpenJDK(), instanceOf(Instrumentation.class)); assertThat(ByteBuddyAgent.install(), instanceOf(Instrumentation.class));
ClassFileTransformer classFileTransformer = new AgentBuilder.Default() ClassFileTransformer classFileTransformer = new AgentBuilder.Default()
.rebase(isAnnotatedWith(ShouldRebase.class), ElementMatchers.is(classLoader)).transform(new QuxTransformer()) .rebase(isAnnotatedWith(ShouldRebase.class), ElementMatchers.is(classLoader)).transform(new QuxTransformer())
.installOnByteBuddyAgent(); .installOnByteBuddyAgent();
Expand All @@ -100,7 +100,7 @@ public void testAgentSelfInitializationAuxiliaryTypes() throws Exception {
@Test @Test
@ToolsJarRule.Enforce @ToolsJarRule.Enforce
public void testAgentWithoutSelfInitializationWithNativeMethodPrefix() throws Exception { public void testAgentWithoutSelfInitializationWithNativeMethodPrefix() throws Exception {
assertThat(ByteBuddyAgent.installOnOpenJDK(), instanceOf(Instrumentation.class)); assertThat(ByteBuddyAgent.install(), instanceOf(Instrumentation.class));
ClassFileTransformer classFileTransformer = new AgentBuilder.Default() ClassFileTransformer classFileTransformer = new AgentBuilder.Default()
.disableSelfInitialization() .disableSelfInitialization()
.withNativeMethodPrefix(QUX) .withNativeMethodPrefix(QUX)
Expand Down
Expand Up @@ -34,14 +34,14 @@ public class ClassFileLocatorAgentBasedTest {
@Test @Test
@ToolsJarRule.Enforce @ToolsJarRule.Enforce
public void testStrategyCreation() throws Exception { public void testStrategyCreation() throws Exception {
assertThat(ByteBuddyAgent.installOnOpenJDK(), instanceOf(Instrumentation.class)); assertThat(ByteBuddyAgent.install(), instanceOf(Instrumentation.class));
assertThat(ClassReloadingStrategy.fromInstalledAgent(), notNullValue()); assertThat(ClassReloadingStrategy.fromInstalledAgent(), notNullValue());
} }


@Test @Test
@ToolsJarRule.Enforce @ToolsJarRule.Enforce
public void testExtraction() throws Exception { public void testExtraction() throws Exception {
assertThat(ByteBuddyAgent.installOnOpenJDK(), instanceOf(Instrumentation.class)); assertThat(ByteBuddyAgent.install(), instanceOf(Instrumentation.class));
ClassFileLocator classFileLocator = ClassFileLocator.AgentBased.fromInstalledAgent(getClass().getClassLoader()); ClassFileLocator classFileLocator = ClassFileLocator.AgentBased.fromInstalledAgent(getClass().getClassLoader());
ClassFileLocator.Resolution resolution = classFileLocator.locate(Foo.class.getName()); ClassFileLocator.Resolution resolution = classFileLocator.locate(Foo.class.getName());
assertThat(resolution.isResolved(), is(true)); assertThat(resolution.isResolved(), is(true));
Expand All @@ -51,7 +51,7 @@ public void testExtraction() throws Exception {
@Test @Test
@ToolsJarRule.Enforce @ToolsJarRule.Enforce
public void testExtractionOfInflatedMethodAccessor() throws Exception { public void testExtractionOfInflatedMethodAccessor() throws Exception {
assertThat(ByteBuddyAgent.installOnOpenJDK(), instanceOf(Instrumentation.class)); assertThat(ByteBuddyAgent.install(), instanceOf(Instrumentation.class));
Method bar = Foo.class.getDeclaredMethod("bar"); Method bar = Foo.class.getDeclaredMethod("bar");
for (int i = 0; i < 20; i++) { for (int i = 0; i < 20; i++) {
bar.invoke(new Foo()); bar.invoke(new Foo());
Expand Down
Expand Up @@ -42,7 +42,7 @@ public void setUp() throws Exception {
public void testBootstrapInjection() throws Exception { public void testBootstrapInjection() throws Exception {
ClassInjector classInjector = new ClassInjector.UsingInstrumentation(folder, ClassInjector classInjector = new ClassInjector.UsingInstrumentation(folder,
ClassInjector.UsingInstrumentation.Target.BOOTSTRAP, ClassInjector.UsingInstrumentation.Target.BOOTSTRAP,
ByteBuddyAgent.installOnOpenJDK()); ByteBuddyAgent.install());
String name = FOO + RandomString.make(); String name = FOO + RandomString.make();
DynamicType dynamicType = new ByteBuddy().subclass(Object.class).name(name).make(); DynamicType dynamicType = new ByteBuddy().subclass(Object.class).name(name).make();
Map<TypeDescription, Class<?>> types = classInjector.inject(Collections.singletonMap(dynamicType.getTypeDescription(), dynamicType.getBytes())); Map<TypeDescription, Class<?>> types = classInjector.inject(Collections.singletonMap(dynamicType.getTypeDescription(), dynamicType.getBytes()));
Expand All @@ -56,7 +56,7 @@ public void testBootstrapInjection() throws Exception {
public void testSystemInjection() throws Exception { public void testSystemInjection() throws Exception {
ClassInjector classInjector = new ClassInjector.UsingInstrumentation(folder, ClassInjector classInjector = new ClassInjector.UsingInstrumentation(folder,
ClassInjector.UsingInstrumentation.Target.SYSTEM, ClassInjector.UsingInstrumentation.Target.SYSTEM,
ByteBuddyAgent.installOnOpenJDK()); ByteBuddyAgent.install());
String name = BAR + RandomString.make(); String name = BAR + RandomString.make();
DynamicType dynamicType = new ByteBuddy().subclass(Object.class).name(name).make(); DynamicType dynamicType = new ByteBuddy().subclass(Object.class).name(name).make();
Map<TypeDescription, Class<?>> types = classInjector.inject(Collections.singletonMap(dynamicType.getTypeDescription(), dynamicType.getBytes())); Map<TypeDescription, Class<?>> types = classInjector.inject(Collections.singletonMap(dynamicType.getTypeDescription(), dynamicType.getBytes()));
Expand Down
Expand Up @@ -42,7 +42,7 @@ public void setUp() throws Exception {
@Test @Test
@ToolsJarRule.Enforce @ToolsJarRule.Enforce
public void testBootstrapInjection() throws Exception { public void testBootstrapInjection() throws Exception {
ClassLoadingStrategy bootstrapStrategy = new ClassLoadingStrategy.ForBootstrapInjection(ByteBuddyAgent.installOnOpenJDK(), file); ClassLoadingStrategy bootstrapStrategy = new ClassLoadingStrategy.ForBootstrapInjection(ByteBuddyAgent.install(), file);
String name = FOO + RandomString.make(); String name = FOO + RandomString.make();
DynamicType dynamicType = new ByteBuddy().subclass(Object.class).name(name).make(); DynamicType dynamicType = new ByteBuddy().subclass(Object.class).name(name).make();
Map<TypeDescription, Class<?>> loaded = bootstrapStrategy.load(null, Collections.singletonMap(dynamicType.getTypeDescription(), dynamicType.getBytes())); Map<TypeDescription, Class<?>> loaded = bootstrapStrategy.load(null, Collections.singletonMap(dynamicType.getTypeDescription(), dynamicType.getBytes()));
Expand All @@ -54,7 +54,7 @@ public void testBootstrapInjection() throws Exception {
@Test @Test
@ToolsJarRule.Enforce @ToolsJarRule.Enforce
public void testClassLoaderInjection() throws Exception { public void testClassLoaderInjection() throws Exception {
ClassLoadingStrategy bootstrapStrategy = new ClassLoadingStrategy.ForBootstrapInjection(ByteBuddyAgent.installOnOpenJDK(), file); ClassLoadingStrategy bootstrapStrategy = new ClassLoadingStrategy.ForBootstrapInjection(ByteBuddyAgent.install(), file);
String name = BAR + RandomString.make(); String name = BAR + RandomString.make();
ClassLoader classLoader = new URLClassLoader(new URL[0], null); ClassLoader classLoader = new URLClassLoader(new URL[0], null);
DynamicType dynamicType = new ByteBuddy().subclass(Object.class).name(name).make(); DynamicType dynamicType = new ByteBuddy().subclass(Object.class).name(name).make();
Expand Down
Expand Up @@ -26,14 +26,14 @@ public class ClassReloadingStrategyTest {
@Test @Test
@ToolsJarRule.Enforce @ToolsJarRule.Enforce
public void testStrategyCreation() throws Exception { public void testStrategyCreation() throws Exception {
assertThat(ByteBuddyAgent.installOnOpenJDK(), instanceOf(Instrumentation.class)); assertThat(ByteBuddyAgent.install(), instanceOf(Instrumentation.class));
assertThat(ClassReloadingStrategy.fromInstalledAgent(), notNullValue()); assertThat(ClassReloadingStrategy.fromInstalledAgent(), notNullValue());
} }


@Test @Test
@ToolsJarRule.Enforce @ToolsJarRule.Enforce
public void testFromAgentClassReloadingStrategy() throws Exception { public void testFromAgentClassReloadingStrategy() throws Exception {
assertThat(ByteBuddyAgent.installOnOpenJDK(), instanceOf(Instrumentation.class)); assertThat(ByteBuddyAgent.install(), instanceOf(Instrumentation.class));
Foo foo = new Foo(); Foo foo = new Foo();
assertThat(foo.foo(), is(FOO)); assertThat(foo.foo(), is(FOO));
ClassReloadingStrategy classReloadingStrategy = ClassReloadingStrategy.fromInstalledAgent(); ClassReloadingStrategy classReloadingStrategy = ClassReloadingStrategy.fromInstalledAgent();
Expand All @@ -51,7 +51,7 @@ public void testFromAgentClassReloadingStrategy() throws Exception {
@Test @Test
@ToolsJarRule.Enforce @ToolsJarRule.Enforce
public void testClassRedefinitionRenamingWithStackMapFrames() throws Exception { public void testClassRedefinitionRenamingWithStackMapFrames() throws Exception {
assertThat(ByteBuddyAgent.installOnOpenJDK(), instanceOf(Instrumentation.class)); assertThat(ByteBuddyAgent.install(), instanceOf(Instrumentation.class));
ClassReloadingStrategy classReloadingStrategy = ClassReloadingStrategy.fromInstalledAgent(); ClassReloadingStrategy classReloadingStrategy = ClassReloadingStrategy.fromInstalledAgent();
Bar bar = new Bar(); Bar bar = new Bar();
new ByteBuddy().redefine(Qux.class) new ByteBuddy().redefine(Qux.class)
Expand All @@ -66,7 +66,7 @@ public void testClassRedefinitionRenamingWithStackMapFrames() throws Exception {
@Test @Test
@ToolsJarRule.Enforce @ToolsJarRule.Enforce
public void testRedefinitionReloadingStrategy() throws Exception { public void testRedefinitionReloadingStrategy() throws Exception {
assertThat(ByteBuddyAgent.installOnOpenJDK(), instanceOf(Instrumentation.class)); assertThat(ByteBuddyAgent.install(), instanceOf(Instrumentation.class));
Instrumentation instrumentation = spy(ByteBuddyAgent.getInstrumentation()); Instrumentation instrumentation = spy(ByteBuddyAgent.getInstrumentation());
Foo foo = new Foo(); Foo foo = new Foo();
assertThat(foo.foo(), is(FOO)); assertThat(foo.foo(), is(FOO));
Expand All @@ -86,7 +86,7 @@ public void testRedefinitionReloadingStrategy() throws Exception {
@Test @Test
@ToolsJarRule.Enforce @ToolsJarRule.Enforce
public void testRetransformationReloadingStrategy() throws Exception { public void testRetransformationReloadingStrategy() throws Exception {
assertThat(ByteBuddyAgent.installOnOpenJDK(), instanceOf(Instrumentation.class)); assertThat(ByteBuddyAgent.install(), instanceOf(Instrumentation.class));
Foo foo = new Foo(); Foo foo = new Foo();
assertThat(foo.foo(), is(FOO)); assertThat(foo.foo(), is(FOO));
ClassReloadingStrategy classReloadingStrategy = new ClassReloadingStrategy(ByteBuddyAgent.getInstrumentation(), ClassReloadingStrategy classReloadingStrategy = new ClassReloadingStrategy(ByteBuddyAgent.getInstrumentation(),
Expand Down

2 comments on commit 1666d0d

@CodingFabian
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great work, when I suggested that, I wasn't aware that this would be such a big change. sorry about that :)

@raphw
Copy link
Owner

@raphw raphw commented on 1666d0d Sep 16, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could have been shorter but this way one could even customize the injection. Thanks for the suggestion!

Please sign in to comment.