diff --git a/byte-buddy-dep/src/main/java/net/bytebuddy/asm/MemberSubstitution.java b/byte-buddy-dep/src/main/java/net/bytebuddy/asm/MemberSubstitution.java index 3c76de36265..efdb69895f2 100644 --- a/byte-buddy-dep/src/main/java/net/bytebuddy/asm/MemberSubstitution.java +++ b/byte-buddy-dep/src/main/java/net/bytebuddy/asm/MemberSubstitution.java @@ -1005,7 +1005,7 @@ public FieldDescription resolve(TypeDescription targetType, ByteCodeElement targ } else if (parameters.get(0).isPrimitive() || parameters.get(0).isArray()) { throw new IllegalStateException("Cannot access field on primitive or array type for " + target); } - TypeDefinition current = parameters.get(0); + TypeDefinition current = instrumentedType; do { FieldList fields = current.getDeclaredFields().filter(not(isStatic()).and(isVisibleTo(instrumentedType)).and(matcher)); if (fields.size() == 1) { @@ -1226,7 +1226,7 @@ public MethodDescription resolve(TypeDescription targetType, ByteCodeElement tar } else if (parameters.get(0).isPrimitive() || parameters.get(0).isArray()) { throw new IllegalStateException("Cannot invoke method on primitive or array type for " + target); } - TypeDefinition typeDefinition = parameters.get(0); + TypeDefinition typeDefinition = instrumentedType; List candidates = CompoundList.of(methodGraphCompiler.compile(typeDefinition, instrumentedType) .listNodes() .asMethodList() diff --git a/byte-buddy-dep/src/test/java/net/bytebuddy/asm/MemberSubstitutionTest.java b/byte-buddy-dep/src/test/java/net/bytebuddy/asm/MemberSubstitutionTest.java index 2844a1da7a8..88ceaa8422d 100644 --- a/byte-buddy-dep/src/test/java/net/bytebuddy/asm/MemberSubstitutionTest.java +++ b/byte-buddy-dep/src/test/java/net/bytebuddy/asm/MemberSubstitutionTest.java @@ -2,11 +2,13 @@ import net.bytebuddy.ByteBuddy; import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.description.modifier.Visibility; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.dynamic.ClassFileLocator; import net.bytebuddy.dynamic.DynamicType; import net.bytebuddy.dynamic.loading.ByteArrayClassLoader; import net.bytebuddy.dynamic.loading.ClassLoadingStrategy; +import net.bytebuddy.implementation.FieldAccessor; import net.bytebuddy.implementation.bytecode.constant.NullConstant; import net.bytebuddy.pool.TypePool; import net.bytebuddy.test.packaging.MemberSubstitutionTestHelper; @@ -598,6 +600,53 @@ public void testMethodMatched() throws Exception { assertThat(type.getDeclaredField(BAR).getInt(instance), is(1)); } + @Test + public void testDefinedFieldMatched() throws Exception { + Class type = new ByteBuddy() + .redefine(MatcherSample.class) + .defineField(BAZ, int.class, Visibility.PUBLIC) + .visit(MemberSubstitution.strict().field(named(FOO)).replaceWithField(named(BAZ)).on(named(FOO))) + .make() + .load(ClassLoadingStrategy.BOOTSTRAP_LOADER, ClassLoadingStrategy.Default.WRAPPER) + .getLoaded(); + Object instance = type.getConstructor().newInstance(); + assertThat(type.getDeclaredMethod(FOO).invoke(instance), nullValue(Object.class)); + assertThat(type.getDeclaredField(FOO).getInt(instance), is(0)); + assertThat(type.getDeclaredField(BAZ).getInt(instance), is(1)); + } + + @Test + public void testDefinedPublicMethodMatched() throws Exception { + Class type = new ByteBuddy() + .redefine(MatcherSample.class) + .defineField(BAZ, int.class, Visibility.PUBLIC) + .defineMethod(BAZ, void.class, Visibility.PUBLIC).withParameters(int.class).intercept(FieldAccessor.ofField(BAZ)) + .visit(MemberSubstitution.strict().field(named(FOO)).replaceWithMethod(named(BAZ)).on(named(FOO))) + .make() + .load(ClassLoadingStrategy.BOOTSTRAP_LOADER, ClassLoadingStrategy.Default.WRAPPER) + .getLoaded(); + Object instance = type.getConstructor().newInstance(); + assertThat(type.getDeclaredMethod(FOO).invoke(instance), nullValue(Object.class)); + assertThat(type.getDeclaredField(FOO).getInt(instance), is(0)); + assertThat(type.getDeclaredField(BAZ).getInt(instance), is(1)); + } + + @Test + public void testDefinedPrivateMethodMatched() throws Exception { + Class type = new ByteBuddy() + .redefine(MatcherSample.class) + .defineField(BAZ, int.class, Visibility.PUBLIC) + .defineMethod(BAZ, void.class, Visibility.PRIVATE).withParameters(int.class).intercept(FieldAccessor.ofField(BAZ)) + .visit(MemberSubstitution.strict().field(named(FOO)).replaceWithMethod(named(BAZ)).on(named(FOO))) + .make() + .load(ClassLoadingStrategy.BOOTSTRAP_LOADER, ClassLoadingStrategy.Default.WRAPPER) + .getLoaded(); + Object instance = type.getConstructor().newInstance(); + assertThat(type.getDeclaredMethod(FOO).invoke(instance), nullValue(Object.class)); + assertThat(type.getDeclaredField(FOO).getInt(instance), is(0)); + assertThat(type.getDeclaredField(BAZ).getInt(instance), is(1)); + } + @Test public void testMethodSelfDelegationSample() throws Exception { Class type = new ByteBuddy()