soc
soc

Reputation: 28443

Recommended bytecode manipulation library for rewriting class files to change types e. g. of fields?

I'm looking for a way to generate a class file from an existing one, while allowing me to replace the type of a field by another type.

Consider this example snippet, in which I'd like to every usage of int bar ...

class Foo {
  private final int bar;

  public Foo(int bar) {
    this.bar = bar;
  }

  public int getBar() {
    return bar;
  }

  public static int of(int bar) {
    return new Foo(bar);
  }
}

with long bar, like this:

class Foo_Long {
  private final long bar;

  public Foo_Long(long bar) {
    this.bar = bar;
  }

  public long getBar() {
    return bar;
  }

  public static Foo_Long of(long bar) {
    return new Foo_Long (bar);
  }
}

I have looked into multiple bytecode manipulation libraries like cglib, javassit and ASM, but they all seem to focus on adding members or replacing one method body with and existing different one.

Is there a library which offers something like ...

byte[] rewriteFieldWithType(Class klazz,
                            Field field,
                            Class type,
                            String newClassName) { ... }

Field field = Foo.class.getDeclaredField("bar");
byte[] newClass = rewriteFieldWithType(Foo.class,
                                       field,
                                       java.lang.Long.TYPE,
                                       "Foo_Long");

... in a fool-proof way? Or would I need to implement all the ugly stuff like fixing the metadata and replacing the different bytecode instructions in method bodies, e. g. iload with lload manually?

Upvotes: 2

Views: 543

Answers (1)

Eugene Kuleshov
Eugene Kuleshov

Reputation: 31795

I don't believe you'd find a framework for such specific bytecode transformation. Since you've mentioned ASM and other bytecode manipulation frameworks, they all are all-purpose frameworks and allow to implement any transformations.

With ASM, the actual transformation will look much simpler than you anticipating, e.g. you can use Type.getOpcode() to get instruction opcode for your new type.

Also, to track source of values on the stack or in local vars, you can use SourceInterpreter from the ASM's analysis package.

Upvotes: 1

Related Questions