2016-05-24 11 views
1

例えば、java.lang.Objectへの参照をすべてsome.packageName.SomeClassに変更したい、コンパイルされたクラス(ソースコードは使用できません)を変更しようとしています。参照することによりコンパイルされたクラス内のすべてのクラス参照を変更する

私は意味:

  • フィールドタイプ
  • 方法は種類
  • メソッドの引数の型
  • スーパータイプを返すメソッド本体内
  • 変数の型
  • 静的クラス参照(例えばjava.lang.Object.classを)
  • 遺伝子RIC型パラメータ

基本的に、この実施例により、修飾されたクラスは、だけsome.packageName.SomeClassを通して、直接java.lang.Objectクラスにアクセスできるようにshould't。サンプルクラスは、jreからの任意のクラスでも、そうでなくてもかまいません。提供された代用品は、元のとおりに動作します。

BCELまたはJavassistを使用すると可能ですか?そうでない場合は、この目標を達成するための機能を提供する他のライブラリがありますか?

+0

コンパイルされたクラス? –

+0

@Vishal Kamat、あなたがなぜそう思うか分からなければ、あなたがする必要がないということです。場合によっては、余分なメソッドを追加したり、ソースコードを持たないクラスにインターフェイスを実装したりするなどの場合に役立ちます。私の場合は単なるサンドボックステストです。 –

+0

その場合、AOPはあなたの友人です。あなたが言及したことをするためのものがたくさんあります –

答えて

1

私は試していませんが、javassistとASMは確かにクラス内の定数プールを変更できます。これは、そのような参照がクラスファイルに格納される場所です。

+0

定数プールを変更すれば十分でしょうか?リフレクションを除いて、他の方法はありますか?定数プールで参照されていないクラスは、別のクラスで引き続き表示されますか? –

+0

すべてのクラス/フィールド/メソッド参照は定数プールを経由します – Nikem

+0

試してみましょう –

0

私はASMを使用しており、これは非常に簡単です。 org.objectweb.asm.commons.Remapperの実装では、クラスの名前と記述子を新しいものに変更します。例えば

方法の一つは次のようになります

@Override 
public String mapDesc(String desc) { 
    return super.mapDesc(StringUtil.fixDesc(desc, renamed)); 
} 

説明は次のようになります。LCOM /例/クラス。。フィールドの名前が ''に変更されたのは、古い値から新しい値を含むクラスマッピングのマップです。私は/ BBBCOM /例/ AAAへのCOM /例を作りたいのであれば、私はマップに前と値の後に供給し、そのように再マップを呼び出す:なぜ誰もが、変更したい

/** 
* Given a map of ClassNodes and mappings, returns a map of class names to 
* class bytes. 
*/ 
public static Map<String, byte[]> process(Map<String, ClassNode> nodes, Map<String, MappedClass> mappings) { 
    Map<String, byte[]> out = new HashMap<String, byte[]>(); 
    RemapperImpl mapper = new RemapperImpl(mappings); 
    for (ClassNode cn : nodes.values()) { 
     ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); 
     ClassVisitor remapper = new ClassRemapper(cw, mapper); 
     cn.accept(remapper); 
     out.put(mappings.get(cn.name).getNewName(), cw.toByteArray()); 
    } 
    return out; 
} 
関連する問題