I have a class like below with a method that just returns a String, but I want to modify what it returns from another class, without hardcoding it myself.
public class Name {
public static String getName() {
return "MyName";
}
}
Is there any way to do this? I tried BCEL but that didn't seem to change the return value.
Edit: This is for a mod. I'm trying to make it completely independant from the existing code, by not modifying it.
Thanks.
Are you sure you've tried BCEL? I created a fully-working example here.
JavaClass target;
try {
target = Repository.lookupClass("Target");
} catch (final ClassNotFoundException ex) {
throw new RuntimeException("unable to resolve Target", ex);
}
final ClassGen targetGen = new ClassGen(target);
final ConstantPoolGen pool = targetGen.getConstantPool();
final ConstantMethodref ref = (ConstantMethodref) pool.getConstant(
pool.lookupMethodref("Name", "getName", "()Ljava/lang/String;"));
ref.setClassIndex(pool.lookupClass("Target"));
ref.setNameAndTypeIndex(pool.addNameAndType("$Name$getName", "()Ljava/lang/String;"));
final InstructionList code = new InstructionList();
final InstructionFactory factory = new InstructionFactory(targetGen, pool);
code.append(factory.createConstant("overriden-name"));
code.append(factory.createReturn(Type.STRING));
code.setPositions();
final MethodGen methodGen = new MethodGen(
Constants.ACC_PRIVATE | Constants.ACC_SYNTHETIC | Constants.ACC_STATIC,
Type.STRING, new Type[0], new String[0], "$Name$getName", "Target",
code, pool);
methodGen.setMaxLocals(0);
methodGen.setMaxStack(1);
targetGen.addMethod(methodGen.getMethod());
try {
targetGen.getJavaClass().dump("Target.class");
} catch (final IOException ex) {
throw new RuntimeException("unable to save Target", ex);
}
C:\dev\scrap>javac Target.java C:\dev\scrap>java Target original-name C:\dev\scrap>javac -cp .;bcel-6.0.jar Instrumenter.java C:\dev\scrap>java -cp .;bcel-6.0.jar Instrumenter C:\dev\scrap>java Target overriden-name