ASM #5: Memakai Agen


Pada tulisan sebelumnya, class hasil transformasi tidak dapat dipakai secara langsung, melainkan harus memakai interface atau superclass-nya. Bagaimana jika aku tetap ingin memakai seperti biasa tanpa membuat interface atau superclass? Salah satu solusi yang mungkin adalah dengan memakai agent. Class tetap dapat dipakai seperti biasa, bahkan tanpa membuat classloader baru. Hal ini karena agent akan dikerjakan saat JVM dijalankan.

JVM akan mencari dan mengerjakan method milik agent class yang definisinya seperti berikut:

public static void premain(String agentArgs, Instrumentation inst);
atau
public static void premain(String agentArgs);

Berikut ini adalah contoh agent class yang aku pakai:

public class Agent {

  public static void premain(String agentArgs, Instrumentation inst) {
    inst.addTransformer(new ClassFileTransformer(){

      @Override
      public byte[] transform(ClassLoader loader, String className,
          Class<?> classBeingRedefined, ProtectionDomain protectionDomain,
          byte[] classfileBuffer) throws IllegalClassFormatException {

        if (className.equals("latihan/Music")) {
          try {

            ClassReader reader = new ClassReader(classfileBuffer);
            ClassWriter writer = new ClassWriter(reader, 0);
            ToStringAdapter adapter = new ToStringAdapter(writer);

            reader.accept(adapter,0);
            return writer.toByteArray();

          } catch (Exception ex) {
            ex.printStackTrace();
          }
        }
        return classfileBuffer;
      }

    });
  }

}

Agent di atas akan melakukan transformasi melalui ToStringAdapter (turunan dari ClassAdapter) yang sudah aku buat di tulisan sebelumnya. Untuk dapat memakai agent ini, aku masih harus membuat jar dari class ini, serta menambahkan manifest yang isinya sebagai berikut:

Manifest-Version: 1.0
Main-Class: latihan.Main
Premain-Class: latihan.Agent
Boot-Class-Path: lib/asm-3.1.jar lib/asm-commons-3.1.jar lib/asm-util-3.1.jar

Entry yang dibutuhkan untuk agent adalah Premain-Class dan Boot-Class-Path. Fungsinya dapat ditebak dari namanya: Premain-Class sama seperti Main-Class, hanya saja ia menyatakan class mana yang merupakan agent. Boot-Class-Path sama seperti Class-Path, hanya saja ia menyatakan classpath yang khusus dipakai oleh agent.

Sekarang, class Music dapat dipakai layaknya class normal lainnya (tentu saja dengan pengecualian sudah punya definisi method toString() secara otomatis):

public class Main {

  public Main() {
    Music m = new Music();
    m.setMusicID("MID-123");
    m.setTitle("TITLE");
    System.out.println("Music = " + m);
  }

  public static void main(String[] args) throws Exception {
    new Main();
  }

}

Btw, untuk menjalankan program di atas, aku tidak lupa menambahkan argument -javaagent agar JVM mengerjakan agent class, seperti:

java -javaagent:latihanASM.jar -jar latihanASM.jar

Perihal Solid Snake
I'm nothing...

Apa komentar Anda?

Please log in using one of these methods to post your comment:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s

%d blogger menyukai ini: