Well, I was late for the answer, but I hope you find it useful anyway (or at least to someone else who needs it).
Even if you can use low-level api bytecode, for example, Raphw suggested in the javassist comment allows you to do this with a higher-level API (which I recommend).
The solution that I will give below will change the field name and change all references from the old field name to the new one, which is likely to be what you want, since you are renaming the field.
Code
Use the Class1 example.
ClassPool classpool = ClassPool.getDefault(); CtClass ctClass = classpool.get(Class1.class.getName()); CtField field = ctClass.getField("strCompany"); CodeConverter codeConverter = new CodeConverter(); codeConverter.redirectFieldAccess(field, ctClass, "strCompany2"); ctClass.instrument(codeConverter); field.setName("strCompany2"); ctClass.writeFile("./injectedClasses");
Accessing and Defining CtField I assume - on your question - you already know how to do this. The trick of โredoingโ all field references is done using CodeConverter which will replace all links to the CtField field for references to a field named strCompany2 in ctClass (which happens in the same class). Keep in mind that this needs to be done before by renaming the field to strCompany2.
At the end of this run, you'll have a new Class1 class in the embeddedbedclasses folder, ready to use strCompany2 instead of strCompany .:-)
Sidenote
Keep in mind that what CodeConverter really does is create a new entry in the Constant Pool class and redirect all links from the old field entry to the field that defines the "new" (read renamed) field.
So in the Class1 example, this is what happens:
Permanent Pool BEFORE Injection
Constant pool: #1 = Class #2 // test/Class1 #2 = Utf8 test/Class1 #3 = Class #4 // java/lang/Object #4 = Utf8 java/lang/Object #5 = Utf8 strCompany #6 = Utf8 Ljava/lang/String; #7 = Utf8 <init> #8 = Utf8 ()V #9 = Utf8 Code #10 = Methodref #3.#11 // java/lang/Object."<init>":()V #11 = NameAndType #7:#8 // "<init>":()V #12 = Utf8 LineNumberTable #13 = Utf8 LocalVariableTable #14 = Utf8 this #15 = Utf8 Ltest/Class1; #16 = Utf8 test #17 = Utf8 ()Ljava/lang/String; #18 = String #19 // TestCompany #19 = Utf8 TestCompany #20 = Fieldref #1.#21 // test/Class1.strCompany:Ljava/lang/String; #21 = NameAndType #5:#6 // strCompany:Ljava/lang/String; #22 = Utf8 SourceFile #23 = Utf8 Class1.java
Permanent pool AFTER injection
Constant pool: #1 = Class #2 // test/Class1 #2 = Utf8 test/Class1 #3 = Class #4 // java/lang/Object #4 = Utf8 java/lang/Object #5 = Utf8 strCompany #6 = Utf8 Ljava/lang/String; #7 = Utf8 <init> #8 = Utf8 ()V #9 = Utf8 Code #10 = Methodref #3.#11 // java/lang/Object."<init>":()V #11 = NameAndType #7:#8 // "<init>":()V #12 = Utf8 LineNumberTable #13 = Utf8 LocalVariableTable #14 = Utf8 this #15 = Utf8 Ltest/Class1; #16 = Utf8 test #17 = Utf8 ()Ljava/lang/String; #18 = String #19 // TestCompany #19 = Utf8 TestCompany #20 = Fieldref #1.#21 // test/Class1.strCompany:Ljava/lang/String; #21 = NameAndType #5:#6 // strCompany:Ljava/lang/String; #22 = Utf8 SourceFile #23 = Utf8 Class1.java #24 = Utf8 strCompany2 #25 = NameAndType #24:#6 // strCompany2:Ljava/lang/String; #26 = Fieldref #1.#25 //test/Class1.strCompany2:Ljava/lang/String;
In this case, with one rewrite field, your constantPool has increased by 3 frames, which are the definition of a new field. This is usually not a problem, but, nevertheless, I rather mentioned this in advance.