2

ゴール

  • 変数と変数のコピーがどこで比較されているかを検出する
  • 操作が発生した行の近くにコードを挿入する
  • コードの目的: クラスが実行されるたびにカウンターを増加させる

汎用: 特定のパラメーターを使用した実行後に行われた比較とコピーの数をカウントします

2つのオプション

注:私は常に最初に.javaファイルを持っています

1) Java ファイルの編集


正規表現との比較を見つけ、行の近くにコードの断片を挿入してから、クラスをコンパイルします (私のアプリケーションは JavaCompiler を使用します)

2) ASM バイトコード エンジニアリングを使用する


また、追跡したいイベントの場所を検出し、バイトコードにピースを挿入してから、(すでにコンパイルされているが変更された)クラスを使用します

私の質問

最善/最もクリーンな方法は何ですか? これを行うより良い方法はありますか?

4

3 に答える 3

1

Java ルートを選択する場合は、正規表現を使用したくありません。実際の Java パーサーが必要です。したがって、それがあなたの決定に影響を与える可能性があります。Oracle JVM には、Java コンパイラを実装する内部プライベート クラスの一部として 1 つが含まれているため、実際に作成したくない場合は自分で作成する必要はありません。しかし、Oracle AST のデコードも 5 分のタスクではありません。そしてもちろん、それが重要な場合、それを使用することは移植性がありません。

ASM ルートを使用すると、セマンティクスがはるかに単純になるため、最初はバイトコードの分析が容易になります。分析の単純さが不慣れさを上回るかどうかは、解決までの正味時間に関しては不明です。最終的に、生成されたコードに関しては、どちらも「優れている」わけではありません。

生成されたJavaソースコードを見て、見たものがそのまま得られることを「知る」ことと、デバッグなどのためにクラスファイルのプリミティブダンプを実行することの明らかな単純さがありますが、その明らかな単純さはすべて、すでに存在するためです。 Java言語の快適さ。しばらく時間をかけてバイトコードを掘り下げると、それも快適になります。そもそもそこにたどり着くのに時間をかける価値があるかどうかという問題です.

于 2012-02-21T23:49:54.417 に答える
1

一般に、どちらのオプションをどれだけ快適に使用できるか、およびパフォーマンスの側面がどれほど重要かによって異なります。バイトコード操作ははるかに高速で、いくらか単純になりますが、バイトコードの仕組みと ASM フレームワークの使用方法を理解する必要があります。

変数アクセスのインターセプトは、おそらく ASM の最も単純な使用例の 1 つです。このAOSD'07ペーパーでは、さらに複雑なシナリオをいくつか見つけることができます。

変数アクセスをインターセプトするための単純化されたコードを次に示します。

ClassReader cr = ...;
ClassWriter cw = ...;
cr.accept(new MethodVisitor(cw) {
  public void visitVarInsn(int opcode, int var) {
    if(opcode == ALOAD) {  // loading Object var
      ... insert method call
    } 
  }
});
于 2012-02-21T23:36:45.803 に答える
0

私だったら、おそらく ASM オプションを使用します。

ASM に関するチュートリアルが必要な場合は、このユーザー作成のチュートリアルを見つけました。ここをクリックしてください。

于 2012-02-21T23:34:55.620 に答える