2009-08-11 16 views
4

コンパイルされたクラスファイルの解析中にメソッド本体内のantherクラスへの呼び出しで置き換えたい...
または別の方法で記述すると、あるメソッド内のあるクラスのメソッドを置き換えて、そのメソッドの部分だけをjavaassistのようなものに置き換えます。例えばコンパイルされたJavaクラス内でのメソッド呼び出しの書き換え

Iは

class A { public int m() { int i = 2; B.multiply(i,i); return i; } } 

のコンパイルされたバージョンを有する場合.. Bの使用を検出し、次いで

class A { public int m() { int i = 2; C.divide(i,i); return i; } } 

を実行するためにコードを変更する方法がある私は、代替を知りますパーサーを使ってソースファイルをgrepすることになりますが、リフレクションを使って新しいコンパイル済みクラスファイルを生成するなど、より洗練されたソリューションを好むでしょう。

どのような考えですか?

+0

免責事項:私はJavaコーダーではありません。 なぜ、問題の関数IEをオーバーライドしないのですか? クラスA2は、{public int m(){int i = 2; C.divide(i、i);私を返す; }} –

+0

[AspectJ](http://www.eclipse.org/aspectj/)のようなAOPフレームワークは、あなたが望むことを実行できるはずです。 – gustafc

答えて

1

コンパイル済みJava用のバイトコードの形式が指定されており、それを操作する製品が存在します。

この​​には、必要な機能があるようです。これらの変換を確実に行うのがどれほど簡単かわかりません。

0

これらの操作は、アプリケーションを起動する前にディスク上の実行可能ファイルが変更されるように、事前に実行する方がずっと簡単です。実行時にメモリ内のコードを操作すると、C/C++でメモリ内のコードを操作するよりも、エラーが発生しやすくなります。なぜあなたはこれをする必要がありますか?

3

@djnaが言うように、あなたがそれらをロードする前に、バイトコードファイルを変更することは可能ですが、あなたはおそらくこれを行うにはしたくない:

  • コード変更を行うコードが複雑になる可能性があると維持するのは難しい。
  • 変更されたコードは、デバッグするのが難しい可能性があります。まず、ソースレベルのデバッガに、実際に編集しているコードに対応していないソースコードが表示されます。

バイトコードの書き換えは、場合によっては便利です。たとえば、JDOの実装では、オブジェクト・メンバーのフェッチを永続性ライブラリへの呼び出しで置き換えるために、バイトコードの再書き込みを使用します。ただし、これらのファイルのソースコードにアクセスできる場合は、ソースコードを前処理(または生成)することによって、より優れた(つまり保守性の高い)ソリューションを得ることができます。

EDIT:また、AOPやGroovyも実行可能な選択肢のように聞こえます。これは、書き換えの程度によって異なります。

+0

ダウン投票者 - なぜかコメントしてください? –

1

Groovyを使用しても構わない場合は、B.multiplyへの呼び出しを傍受し、C.divideに置き換えることができます。例hereがあります。

2

BCELまたはASM

私は最近、Javaクラスファイルを読み込むためのライブラリをいくつか見てきました。 BCELは最も速く、依存関係の数が最も少なく、コンパイルされており、シンプルなAPIを使いました。私はBCMをASMに優先しました。なぜなら、ASMにはより多くの依存性があるからです(APIは評判が良いほど簡単ですが)。

前述のように、AspectJは別の実行可能なオプションです。

BCELは本当に簡単です。あなたは、3行のコードでメソッドのリストを取得することができます。

ClassParser cp = new ClassParser("A.class"); 
JavaClass jc = cp.parse(); 
Method[] m = jc.getMethods(); 

方法の指示を得るために、私は信じている、方法を含め、さらにイントロスペクションのために、他のAPIの施設があります。しかし、このソリューションはAspectJより面倒になる可能性があります。

操作を呼び出すコードのすべてのインスタンスを変更しようとするのではなく、乗算または除算のメソッド自体を変更することもできます。それはBCEL(またはASM)で取るのが簡単な道です。

関連する問題