問題タブ [java-bytecode-asm]
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 - 休止状態の org.objectweb.asm.classwriter
休止状態で作業している Java アプリケーションを実行すると、このエラーが発生します。
java.lang.NoSuchMethodError: org.objectweb.asm.ClassWriter
そして、私はasmのすべての瓶を追加しました
コンソール:
java - ASM - Java クラス名を Java バイトコード名から変換するにはどうすればよいですか?
私は ASM (バイトコード変更ライブラリ) を使用しており、バイトコード命名形式の型名へのアクセスを提供します。たとえば、String フィールドには次の説明があると報告されています: Ljava/lang/String
一部のクラスでは Class.forName を呼び出す必要がありますが、そのための型名のソース コード形式が必要です (例: java.lang.String)。
内部名から Java ソース形式に変換する方法はありますか?
java - 「最終」は実行時に最終ですか?
私はASMをいじってきましたが、クラスのインスタンス フィールドに final 修飾子を追加することに成功したと思います。ただし、その後、上記のクラスをインスタンス化し、セッターを呼び出して、現在の最終フィールドの値を正常に変更しました。バイトコードの変更に何か問題がありますか、それとも最終的には Java コンパイラによってのみ強制されますか?
更新: (7 月 31 日) ここにいくつかのコードがあります。主なパーツは
private int x
とprivate final int y
を含む単純な POJO- MakeFieldsFinalClassAdapter は、アクセスするすべてのフィールドを最終的なものにします。
- AddSetYMethodVisitor は、POJO の setX() メソッドによって、x に設定した値と同じ値に y も設定します。
つまり、1 つの最終 (x) フィールドと 1 つの非最終 (y) フィールドを持つクラスから始めます。x を final にします。x の設定に加えて、setX() で y も設定します。私たちは走る。x と y の両方がエラーなしで設定されます。コードは github にあります。次の方法で複製できます。
2 つの注意事項:そもそもこの質問をした理由: final にしたフィールドと既に final になっているフィールドの両方に、通常のバイトコード命令であると思われるものを設定できます。
別の更新: (8 月 1 日) 1.6.0_26-b03 と 1.7.0-b147 の両方でテストされ、同じ結果が得られました。つまり、JVM は実行時に最終フィールドを問題なく変更します。
最終(?) 更新: (9 月 19 日) かなり長いので、この投稿から完全なソースを削除しますが、github では引き続き利用できます (上記参照)。
私は、JDK7 JVM が仕様に違反していることを決定的に証明したと信じています。( Stephen の回答の抜粋を参照してください。) 前述のように ASM を使用してバイトコードを変更した後、それをクラス ファイルに書き戻しました。優れたJD-GUIを使用して、このクラス ファイルは次のコードに逆コンパイルされます。
これを少し見てみると、 final フィールドを再割り当てするためにクラスがコンパイルされないことがわかりますが、プレーンなバニラ JDK 6 または 7 でそのクラスを実行すると、次のようになります。
- これに関するバグを報告する前に、他の誰かが意見を持っていますか?
- これがJDK 6のバグなのか、それとも7だけのバグなのか、誰でも確認できますか?
bytecode-manipulation - バイト コード インストルメンテーション - ネイティブまたは Java エージェントを実装しますか?
バイト コード インストルメンテーションを使用してプロファイラーを実現したい場合、 JVMTIを使用してネイティブ エージェントを作成する必要がありますか、それともパッケージを使用してJava エージェントを作成する必要がありますか?java.lang.instrument
ASMのようなライブラリを使用したい場合 (本格的なプロファイラーを作成する場合は必須のようです)、Java エージェントを使用する必要があります。ネイティブ エージェントは Java エージェントができることすべてを実行できると思っていたので、これは私を混乱させます。しかし、私には、Java エージェントを作成する方が簡単に思えます。
代替手段はありますか?とにかくJavaエージェントとネイティブエージェントを組み合わせて使用する必要がありますか?
java - インターフェースを使用してバイトコードクラスにアクセスする Java OW2 ASM
ASMでバイトコードクラスがキャストされているインターフェースを介してバイトコードクラスにアクセスするためのガイド/ヘルプをWebで検索しようとしています。これは、 https://github.com/powerbot/RSBotからソースを取得した powerbot (RSBot) と呼ばれる RuneScape ボットで行われているのを見てきました。しかし、すべてのメソッドの「スケルトン」を含むインターフェイスにクラスをキャストするときにクラスキャスト例外が発生するため、それがどのように行われるのか理解できません.クラスをインターフェイスにキャストできるように考えるのは愚かなことだと思います..私はいくつかの準備が必要であることを知っていますが、ASM book/ebook (http://download.forge.objectweb.org/asm/asm-guide.pdf) には、私が読んだ限りでは何もありません。新しい RS ボットを作成するためではなく、必要に応じて BCEL を置き換えるためにこのクールなライブラリを学習することに、私は本当に興味があります。この問題をよりよく理解するために、簡単な例を示します。
ここに「helloSO」というクラスがあります
ここには「helloSO」というインターフェースもあります
私が読んで定義した.classをASMでそのインターフェイスにキャストして、そのインスタンスから名前でメソッドを呼び出すことができるようにしたいと思います..これについて十分に説明したいと思います. 必要に応じて、RSBot をチェックして、私が意味することをよりよく理解することができます。:)だから私が求めているのは; どのような準備が必要で、どこでそれらについて学ぶことができますか? 私はあなたに私にクラスアダプターを作成するように頼んでいるわけではありませんし、何かアドバイスや助けを求めているわけでもありません:) よろしくお願いします!
java - 実行時に抽象メソッドを実装しますか?
抽象クラスがあるとしましょう:
実行時に拡張してClassオブジェクトを作成したいと思います。動的に生成されたクラスを持つことができれば幸いです。
これはClassオブジェクトで表され、リフレクションを使用しての新しいインスタンスを作成できます。重要なのは、実行時にメソッドfoo()の戻り値を決定したいということです。私の考えは、ASMを使用してクラスのバイトコードを作成し、次にClassLoaderオブジェクトでリフレクションを使用してクラスを定義することです。
ASMを使用してから、生成されたバイトにメソッドClassLoader#defineClassを反映することが、ハードコードされていない値を使用して実行時に抽象メソッドを実装するための最良の方法ですか?
はいの場合、どうすればそれを実行できますか。私の腸はASMifierClassVisitorを利用することですが、それを行う正確な方法についてはよくわかりません。他のすべてが失敗した場合、特定のクラスを定義するために必要なJVM命令を手動で実行できることは知っていますが、もっと簡単な方法があるはずだと思います。
いいえの場合、最善の方法は何ですか。また、最善の方法をどのように使用しますか。
編集:私はすべての答えをチェックしました、そして私はそれらのどれも私が探していたものではないと決めました。最終的に、ASMで話していたものの小さな実装を作成しました。ここに投稿する必要があると思いました:
java - ASMによるJavaバイトコード操作
ASM 3.3.1 を使用しています。クラスをインターセプトし、そのメソッドの 1 つを変更しようとしています。org.objectweb.asm.util.ASMifierClassVisitor を使用して、新しいメソッドを作成するための ASM コードを取得しています。すべてがうまく機能しますが、if() ステートメントを理解できません。結果の asm コードを if ステートメント (またはループ) で使用しようとすると、実行時に「スタック サイズが大きすぎます」というエラーが発生します。ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES); を使用しています。これが ASMIFY コードです。
if() ステートメントを ASMIFYING しているときにのみエラーが発生する理由がわかりましたか? どんな助けでも大歓迎です。
私がASM化しているコード。(注:私が使用しているのはそれだけなので、メソッドを取り出しました)
元のメソッドには最後の 2 行だけが含まれています
これはよく見えません。私は CheckClassAdapter.verify() メソッドを使用し、いじっているクラスの一部に対してこれを取得しました。
java - 特定の jvm バイトコード パターンの grep
私は、多くの設計上の問題があるレガシー Java プロジェクトに取り組んでいます。その結果、コードの一部が期待どおりに動作しません。次のコードを検討してください。
上記のコードから、getChildren() が配列への参照を返すことがはっきりとわかります。したがって、次のように配列の要素を変更することができます。
コードの一部が上記のようなことを行っており、これを見つけるのに苦労しています (grep は役に立ちません)。
jvm バイトコード分析を使用してこのパターン (badcode) を見つけるのに役立つツールはありますか、それともどのようにしますか?
注: いくつかの制約により、親の実装を変更することはできません。
ありがとう!
java - Asm ClassReader 受け入れ
メソッド情報を取得するために、Asmを使ってJavaバイトコードを訪問しています.クラスClassReaderのacceptメソッドが非同期で呼び出されているようです.そのため、すぐにメソッド情報を取得することはできません.どうすればよいですか?