This is my object class:
package com.example;
public class Car {
private String name;
private String model;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
This is operation class:
package com.example;
public class Call1 {
public static String callMethod1(){
return "Hello from callMethod1";
}
public static Car callingCall2(){
Call2 call = new Call2();
Car args= call.callMethod2();
return args;
}
}
This is another class:
package com.example;
public class Call2 {
public Car callMethod2(){
Car car = new Car();
car.setModel("2009");
car.setName("mustang");
return car;
}
}
This is my test class:
package com.example;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.agent.ByteBuddyAgent;
import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.agent.builder.AgentBuilder.RedefinitionStrategy;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.asm.Advice.OnMethodEnter;
import net.bytebuddy.asm.AsmVisitorWrapper;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.dynamic.DynamicType.Builder;
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
import net.bytebuddy.dynamic.loading.ClassReloadingStrategy;
import net.bytebuddy.implementation.FixedValue;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.matcher.ElementMatcher;
import net.bytebuddy.matcher.ElementMatchers;
import net.bytebuddy.utility.JavaModule;
import org.junit.Test;
import java.lang.instrument.Instrumentation;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import static net.bytebuddy.matcher.ElementMatchers.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.junit.Test;
public class CallingTest {
@Test
public void givenCall1_whenRedefined_thenReturnFooRedefined() throws
Exception {
premain(null, ByteBuddyAgent.install());
/* Car carTest = new Car();
carTest.setModel("2011");
carTest.setName("Maruti");
ByteBuddyAgent.install();
new ByteBuddy()
.redefine(Call1.class)
.method(named("callingCall2"))
.intercept(FixedValue.value(carTest))
.make()
.load(Car.class.getClassLoader(),
ClassReloadingStrategy.fromInstalledAgent());*/
Call1 f = new Call1();
assertEquals(f.callingCall2().getModel(), "2011");
assertEquals(f.callingCall2().getName(), "Maruti");
}
public static void premain(String arguments, Instrumentation instrumentation) {
new AgentBuilder.Default()
.disableClassFormatChanges()
.with(RedefinitionStrategy.RETRANSFORMATION)
.type(is(Call1.class))
.transform(new AgentBuilder.Transformer() {
/* @Override
public DynamicType.Builder transform(DynamicType.Builder builder,
TypeDescription typeDescription,
ClassLoader classloader) {
return builder.method(named("toString"))
.intercept(FixedValue.value("transformed"));
}*/
@Override
public Builder<?> transform(Builder<?> builder, TypeDescription typeDescription,
ClassLoader classLoader, JavaModule arg3) {
Car carTest = new Car();
carTest.setModel("2011");
carTest.setName("Maruti");
return builder.method(named("callingCall2")).intercept(MethodDelegation.to(MyAdvice.class));
// return builder.visit((AsmVisitorWrapper) Advice.to(Advice.class).on(ElementMatchers.named("callingCall2")));
}
}).installOn(instrumentation);
}
class MyAdvice {
@OnMethodEnter
Car foo() {
Car carTest = new Car();
carTest.setModel("2011");
carTest.setName("Maruti");
return carTest;
}
}
}
The requirement is to override the value of object Car in this scenario such that test class should pass. I tried using byte buddy and AgentBuilder for doing so. When I tried using redefine, it threw error which is 'java.lang.UnsupportedOperationException: class redefinition failed: attempted to change the schema (add/remove fields)' When I tried using AgentBuilder, it is not affecting assertion resulting it to fail. I am newly introduced to byte-buddy so please help achieving requirement.