問題タブ [javassist]
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 - Java リフレクションと Javassist
現在、Java Reflection を使用して反射プロパティを実現しています。反射特性を実現するためのツールがたくさんあることを理解しています。その中の 1 つは、Javassist です。Javassist は、行動のリフレクションとともに、構造的なリフレクションを提供します。ただし、私は行動の反映についてのみ心配しています。
私の質問は、既存のライブラリ (Java リフレクション/Javassist/その他) のうち、動作リフレクションを達成するのに適しているものはどれですか? 私はパフォーマンス (つまり、彼らが行動する速度) だけを心配しています。
前もって感謝します。
java-bytecode-asm - 動的 Java バイトコード操作フレームワークの比較
動的なバイトコードの生成、操作、およびウィービング用のフレームワークがいくつかあります (BCEL、CGLIB、javassist、ASM、MPS)。それらについて知りたいのですが、それらすべてについてすべての詳細を知る時間はあまりないので、一方と他方の長所と短所を示した比較表のようなものと、その説明を見てみたいと思います。どうして。
ここSOで、似たようなことを尋ねる多くの質問を見つけました.答えは通常、「cglibまたはASMを使用できます」、または「javassistはcglibよりも優れています」、または「BCELは古くて死にかけています」または「ASMはX と Y が得られるので最適です。」これらの回答は役に立ちますが、私が望む範囲で質問に完全に答えるわけではなく、それらをより深く比較し、それぞれの長所と短所を示しています。
javassist - Javassist を使用してメソッドを呼び出す
私は Javassist の初心者で、いくつかのチュートリアルを試しています。Javassist がバイトコードを操作し、構造的なリフレクションを実現するのに役立つことを理解しています。ウィキ ( http://en.wikipedia.org/wiki/Javassist ) で言及されているように、リフレクションを実現するためのサポートがあると思います。
Java リフレクションがメソッドを呼び出すのにかかる時間と javassist がかかる時間を理解するために、基本的な評価をしようとしています。その過程で、クラスがあると仮定します。
ここで、Java リフレクション API を使用して、次のコードを使用して、100 個のオブジェクトを呼び出すのにかかる時間を計算します。
さて、javassist の進め方がわかりません。つまり、
ctclass オブジェクトを作成し、読み取るクラスを保存します。また、getdeclaredmethods を使用してすべての宣言済みメソッドを取得し、それを ctMethod 変数に格納することもできます。
しかし、javassist の ctMethod API には、Java リフレクション API とは異なり、invoke メソッドが見つかりません。これは、 http ://www.ibm.com/developerworks/java/library/j-dyn0916/index.html で説明されているように、重複したメソッドを作成し、元のメソッドを呼び出す必要があることを意味します。
これが正しい方法であるかどうかはわかりません。
何か不足していますか?
java - Java バイトコードからの命令の削除
Javassistを使用して、ロード時にクラスを動的に操作しています。Javassist を使用するとメソッドにコードを追加するのは比較的簡単ですが、コードを削除する方法を見つけることができませんでした。
現時点では、nop命令を使用して対象のオペコードとパラメーターを置き換えることで、コードの削除をシミュレートしています。ただし、これはほとんどハックだと思います。
パラメータのバイト長が異なるため、各オペコードを個別に処理する必要があります。場合によっては、削除されたオペコードがスタックに影響を与えるかどうかに応じて、nopとpopのどちらかを選択する必要もあります。この種の操作は退屈になり始めており、それを行うコードはそれに応じて複雑になっています。したがって、当然、既存のソリューションを望んでいます。
最終結果はnop命令で埋められます。JVM はパフォーマンスに影響を与えずにこれらを最適化する必要がありますが、結果のバイトコードは依然として非常に洗練されておらず、必要以上に大きくなっています。これは美学の問題ですが、それでも考慮すべき事項です。
残念ながら、バイトコード配列の一部をシフトしてギャップを埋めるだけでは十分ではありません。移動したコードへの参照 (分岐命令インデックスなど) もすべて更新する必要があります。
Javassist を使用して命令を削除することは可能ですか? あるいは、基本的に自分でバイトコードを解析しなくても、簡単にそれを行うことができるバイトコード操作ライブラリはありますか?
java - Javassist - メソッドへのフィールド アクセスのリダイレクト (機能しません)
私は次のクラスを持っています
以下を使用して計測します。
これを呼び出すと:
私に与えます
私は何が欠けていますか?簡単に達成できるはずのことの1つに思えます。
すべてのクラスで一括「fieldAccess.replace」を実行する必要があるとは言わないでください。OO
java - Javassist:オブジェクトがプロキシかどうかを確認します
私はjavassist.util.proxy.ProxyFactory
自分のプロジェクトでいくつかのプロキシを作成するために使用しています。また、コードの他の部分では、オブジェクトがプロキシされているかどうかを確認できるようにしたいと思います。
だから私の質問は:オブジェクトがプロキシであるかどうかをチェックする方法はありますか?
たとえば、クラスUserがあり、そのプロキシオブジェクトを作成すると、デバッガーではそのクラスはUser_$$_javassist_11
です。instanceof
この目的に使用できる類似のものはありますか?
java - Javassist プロキシの命名ポリシーを変更する
Enhancer を使用して CGLib でプロキシを作成する場合、呼び出し.setNamingPolicy(NamingPolicy n)
てプロキシ クラスの命名規則を CGLib のデフォルト以外のものに変更できます。ProxyFactory を使用するときに Javassist で同様のことを行う方法はありますか?
java - javassistを使用して、非プリミティブフィールドを既存のクラスに追加できますか?
私はJavassistの初心者であり、それに関連するいくつかのチュートリアルをすでに読んでいます。
各メソッドでバイトコードインジェクションを実行する必要があるため、メソッドの入力または終了の前に、これからいくつかの統計を取得します。
オンラインのjavassitチュートリアルを通じて、既存のクラスに新しいフィールドを作成できることがわかりました。
ただし、CtFieldの型にはデフォルトでプリミティブ型しか含まれていません。たとえば、ArrayListなど、型が非プリミティブである新しいフィールドを追加できますか?
新しいArrayListフィールドを既存のクラスに追加できる場合、クラスはjava.util.ArrayListをインポートしないため、コンパイルエラーが発生しますか?
java - javassist を使用して操作データを取得する
単純なクラスを使用して javassist でバイトコードを分析しようとしていますMyData
:
このクラスに対して実行しているコードは次のとおりです。
それは動作し、印刷します:
35 行add()
目で、 という名前のコレクションのメソッドを呼び出しますstrings
。私が投稿したコード スニペットはinvokeinterface
、35 行目のみを取得します。OK、それがクラス フィールド ( ) であることがわかりgetfield
ます。
残りの情報を取得する方法を知りたいです。
- フィールド名は
strings
- 呼び出されるインターフェースメソッドは
add()
これまでのところ、グーグルでも API ドキュメントを読んでも、肯定的な結果は得られていません。
java - PlayFrameworkでjavassistクラスを取得する
モデルクラスへのCtClass参照を取得しようとしています。私は最も単純なバージョンから始めました、
ClassPool.getDefault().get(className);
そしてそれはうまくいきました。しかし、私のマシンでのみ。サーバーでは動作しません。
とにかく、Playframeworkはクラスをtmp / classesに保存するので、バージョンは機能しないはずだと思います。だから今までに私はこのバージョンで終了しました:
しかし、私はこのバージョンについてはよくわかりません。それは常に機能しますか?より良いオプションはありますか?
ClassClassPathとLoaderClassPathも使用してみましたが、成功しませんでした。