問題タブ [bytecode-manipulation]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
java - Oracle と Eclipse のコンパイラによって生成される Java バイトコードの違い
私たちのプロジェクトは、いくつかの Java バイトコード インストルメンテーションを行います。そして、奇妙な行動に出くわしました。次のコード スニペットがあるとします。
Oracle の javac は、上記を次のバイトコードにコンパイルします。
そしてEclipseのコンパイラを次のようにします:
ご覧のとおり、Oracle コンパイラは「new」の後に「dup」を生成しますが、Eclipse は生成しません。新しく作成された Integer インスタンスはまったく使用されないため、このユースケースではまったく正しいので、「複製」は必要ありません。
私の質問は次のとおりです。
- 異なるコンパイラ間の違いの概要はありますか? 記事/ブログ投稿?
- 「new」と「invokespecial」の間に「重複」がない場合、オブジェクトは初期化後に使用されないと安全に結論付けることができますか?
java - javassist を使用して操作データを取得する
単純なクラスを使用して javassist でバイトコードを分析しようとしていますMyData
:
このクラスに対して実行しているコードは次のとおりです。
それは動作し、印刷します:
35 行add()
目で、 という名前のコレクションのメソッドを呼び出しますstrings
。私が投稿したコード スニペットはinvokeinterface
、35 行目のみを取得します。OK、それがクラス フィールド ( ) であることがわかりgetfield
ます。
残りの情報を取得する方法を知りたいです。
- フィールド名は
strings
- 呼び出されるインターフェースメソッドは
add()
これまでのところ、グーグルでも API ドキュメントを読んでも、肯定的な結果は得られていません。
java - javassistを使用してjava演算子をバイトコードのメソッドに置き換えます
私の目標
実行時に比較が行われるタイミング(または、*、-、/、>、<、..などの他の操作)を検出できるようにするため。
これは、Javassistまたはow2ASMを使用してクラスのバイトコードを編集するために実現する必要があります
達成しなければならないこと
このコード
になる必要があります
greatThanは、「>」とまったく同じ結果を返しますが、比較の量を節約するためにも使用されます。その後、比較が行われるたびに外部クラスに通知されます。
追記
それは、手術があるところならどこでも行われなければなりません。したがって、ifステートメントだけではありません。
これの意味は
またになる必要があります
Javassistまたは他のライブラリでこれを実現する方法について何か提案はありますか。
IFLT、IFGTなどのオペコードと関係があると思います
java - Java バイトコードの任意のシーケンスを抽出して実行する
Java クラス A の .class ファイルが与えられた場合、(たとえば BCEL、ASM などを使用して) 特定のバイトコード シーケンスを抽出し (それが基本ブロックであると仮定)、別の場所に配置し、後で実行する方法はありますか?バイトコードのそのシーケンス?
例: ソース コードには ... a += b; という行があります。b += 21; . .
私はバイトコード表現にしかアクセスできません。これらのバイトコードを抽出して、ブラック ボックスとして扱いたいと考えています。クラス A の指示では、ソース行の代わりに「a += b;」欠落している適切なバイトコード シーケンスを保持するこの外部ブラック ボックス X をポイントする必要があります。スタック フレーム上のすべての必要な変数 (たとえば、a、b の現在の値、おそらくブラック ボックス X で使用されるメソッド パラメーターなど) をブラック ボックスにフィードし、バイトコード シーケンスの実行後に、ブラック ボックスは、新しく更新されたフレーム変数とともに元のクラス A に制御を戻します...
アイデアをありがとう。
編集:
以下に示すように、ブラック ボックスはスタブ クラス ファイル内のスタブ メソッドであることが最も合理的です。問題は、この命令シーケンスからこの整形式のスタブ クラスとメソッドを最も合理的に作成する方法と、元のクラス A から制御を移す方法です。理想的には、これはコンパイル時に「オフライン」で行われます。時間。
bytecode-manipulation - capファイルのバイトコードオフカードベリファイア
オフカード バイト コード検証ツールを使用して、Java Card プログラム (cap ファイル) を検証する必要があります。cap ファイルの情報を手動で変更しましたが、新しい cap ファイルのタイプが適切かどうかを確認したいと考えています。
com.sun.javacard.scriptgen.CAP.verifyCAP() メソッドを使用しようとしています。有効な cap ファイルと無効な cap ファイルを送信しましたが、結果は常に 0 です。
java - 注釈/バイトコード織りによる所有権/祖先階層/グループメンバーシップの追跡?
GUI フレームワークでは、親子関係を明示的に追跡するのが一般的です。任意の GUI コンポーネントを指定すると、それを「所有」するコンポーネントの階層を上に移動できます。
親コンポーネントは、実際に子を作成したエンティティであるとは限りません。通常、これらの関係は作成後に構成されます。
私が興味を持っているのは作成関係、つまり、あるオブジェクトが別のオブジェクトを作成した状況です。
関連するオブジェクトは異なるクラスに属し、通常、それらの間に継承関係などはありません。
本当に私はIDを持つ「マスター」オブジェクトを作成し、これらのオブジェクトによって(直接またはn度の分離で)作成されたすべてのオブジェクトに、特定の「マスター」オブジェクトのIDを知ってもらいたいです。
[ id は、実際にはロギングの目的でのみ重要です。]
私はこのようなものを想像することができました:
Master オブジェクトの場合、ID はそのコンストラクターで設定されます。@InheritGroupId でマークされたクラスは、構築時に何らかの方法でスタックを検索し、@GroupId アノテーションを介してグループ ID を直接知っているか、このクラスと同じ方法でグループ ID を決定した最初の呼び出し元オブジェクトを探します。これも @InheritGroupId でマークされていました。
group-id 値にどのようにアクセスするかはわかりません。上記のコードでは、アクセスしたい場所で XXX を使用しただけです。
「どうにかしてスタックを調べろ」と言いますが、私の知る限り、そのままの Java ではこのようにスタックを調べることはできません。
たぶん、スタック検査を必要としない代替構造が可能です。それとも、ある種の AOP バイト ウィービング アプローチが可能でしょうか?
現在、システム内のほぼすべてのオブジェクトに明示的なコンストラクター引数として groupId を渡しています。すべてのオブジェクトが、実際にはロジックの一部ではなく、純粋にログ記録に使用されるメンバー変数を維持する必要があることは、私には残念なことです。
groupId を明示的に渡すことには、下位の何かと私の「マスター」オブジェクトの 1 つとの間に作成者の関係を確立することが難しい状況を明確に指摘できるという利点があります。
私が説明したことを注釈やバイトコード ウィービングで処理する方法について何らかのアイデアがある場合、またはグループ ID を明示的に渡すことが実際には最良の方法であると考えている場合、またはほとんど同じことを達成する方法についてまったく異なる考えをお持ちの場合事、それから私に教えてください。
/ジョージ
更新:特定のマスター オブジェクトのすべての「子」オブジェクトが、特定の時点ですべて事前に作成されるわけではないことに注意してください。まとめて作成されるため、何らかの方法でこのシングルトンにアクセスします。
java - コンパイル済みクラスの文字列定数を変更する
デプロイされた Java プログラムの文字列定数、つまりコンパイルされたファイル内の値を変更する必要があります.class
。再起動することはできますが、簡単に再コンパイルすることはできません (ただし、この質問で答えが得られない場合は不便です)。これは可能ですか?
更新: 16 進エディターでファイルを見たところ、文字列を簡単に変更できるようです。それは機能しますか、つまり、ファイルの何らかの署名を無効にしないでしょうか? 古い文字列と新しい文字列はどちらも英数字で、必要に応じて同じ長さにすることができます。
更新 2: 修正しました。変更が必要な特定のクラスは非常に小さく、プロジェクトの新しいバージョンでは変更されていないため、それをコンパイルしてそこから新しいクラスを取得することができました。ただし、教育目的で、コンパイルを含まない回答にまだ興味があります。
java-bytecode-asm - Javaで実行時に余分なコードを追加する
ライブラリを開発しており、実行時にオブジェクトのメソッドの一部にコードを追加する必要があります。ここには2つのポイントがあります。まず第一に、余分なコードを追加したかったプログラムは、他の誰かによって以前に書かれており、編集したくありませんでした。第二に、私の仕事は、メソッドを呼び出す前にアスペクトを追加することに非常に似ています。
インターネットで検索して読んだ後、この仕事を行うことができるaspectj、ASPECTWERKZなどの多くのフレームワークを見つけましたが、たとえば、aspectj(春のコンテキストで使用する場合)の問題は、APIを提供しないことです実行時にウィービングを行います。また、ASM や javassist などのようなライブラリがいくつかあることもわかりましたが、それらは非常に一般的で習得が難しく、私の仕事はアスペクトの可能性が高いです。
それで、あなたは何を提案しますか?そこに良いライブラリはありますか?先ほど言及した上記のライブラリについて間違っていますか? 助けてください!
java - ASMを使用して初期化子で静的最終フィールドを追加するには?
ASM を使用して static final フィールドを .class ファイルに追加したいのですが、ソース ファイルは
逆コンパイルされて生成されたクラスは次のようになります。
結論として、ASM を使用して .class ファイルに FIRST および SECOND 定数を追加したいのですが、どうすればよいですか?
java - Javaクラスファイルから一部のオペコードを削除するにはどうすればよいですか?
いくつかのコード行を次に示します。
サンプルJavaクラスファイルのバイトコードです。
Javaクラスファイルから47行目、50行目...のオペコードを削除したい。
ASM を使用してこれを行うにはどうすればよいですか?