FAQ - よくある質問
一般的な質問
bytekinとは何ですか?
bytekinはASM上に構築された軽量なJavaバイトコード変換フレームワークです。ソースコードに触れることなく、バイトコードレベルでJavaクラスを変更できます。
なぜバイトコード変換が必要なのですか?
一般的なユースケース:
- ソースコードを変更せずにログを追加
- 横断的関心事の実装
- テストとモック
- パフォーマンスプロファイリング
- セキュリティ強化
bytekinは他のツールとどう違いますか?
ツール | サイズ | 複雑さ | ユースケース |
---|---|---|---|
bytekin | 小 | シンプル | 直接的なバイトコード操作 |
Spring AOP | 大 | 複雑 | エンタープライズフレームワーク |
Mockito | 中 | 中 | テスト/モック |
Aspect | 中 | 複雑 | アスペクト指向プログラミング |
bytekinは本番環境対応ですか?
はい、bytekinは本番環境での使用を目的として設計されています。最小限の依存関係(ASMのみ)で、徹底的にテストされています。
技術的な質問
bytekinはどのJavaバージョンをサポートしていますか?
bytekinはJava 8以降が必要です。
bytekinをSpring Bootと一緒に使用できますか?
はい! bytekinはSpring Bootと並行して動作できます。通常、カスタムClassLoader
セットアップ中またはビルド時に変換を適用します。
bytekinは難読化されたコードで動作しますか?
はい、マッピングで! 難読化されたクラス名とメソッド名を処理するためにマッピングシステムを使用します。
複数の変換を組み合わせることはできますか?
はい! 同じクラスに複数の@Inject
、@Invoke
、その他のアノテーションを使用できます。すべてが適用されます。
使用方法に関する質問
メソッドのメソッドディスクリプタを見つけるにはどうすればよいですか?
javap
を使用:
javap -c MyClass.class
メソッドシグネチャを確認し、JVMディスクリプタ形式に変換します:
int add(int a, int b)
→(II)I
String process(String s)
→(Ljava/lang/String;)Ljava/lang/String;
InjectとInvokeの違いは何ですか?
- Inject: メソッドの特定の箇所にコードを挿入
- Invoke: メソッド内のメソッド呼び出しをインターセプトし、必要に応じて引数を変更
メソッドの実行をキャンセルできますか?
はい、フックメソッドでci.cancelled = true
を設定します。ただし、これは特定の変換タイプでのみ機能します。
メソッド引数を変更するにはどうすればよいですか?
CallbackInfo.modifyArgs
を使用:
ci.modifyArgs = new Object[]{ modifiedArg1, modifiedArg2 };
フックメソッドから静的フィールドにアクセスできますか?
はい、フッククラスから静的フィールドを参照できます:
@Inject(...)
public static CallbackInfo hook() {
// 静的フィールドにアクセス
if (cacheEnabled) {
// ...
}
}
パフォーマンスに関する質問
bytekinを使用するオーバーヘッドは何ですか?
- 変換時間: 最小限、クラスロード時に1回のみ発生
- ランタイムオーバーヘッド: ゼロ! 変換されたバイトコードは手書きのコードと同じ速度で実行
各変換ごとにトランスフォーマーを再ビルドする必要がありますか?
いいえ! 1回ビルドして再利用:
// 良い
BytekinTransformer transformer = new BytekinTransformer.Builder(MyHooks.class).build();
for (String className : classNames) {
byte[] transformed = transformer.transform(className, bytecode);
}
// 悪い
for (String className : classNames) {
BytekinTransformer transformer = new BytekinTransformer.Builder(MyHooks.class).build();
byte[] transformed = transformer.transform(className, bytecode);
}
バイトコード変換は起動時間にどれだけ影響しますか?
変換がシンプルで、必要なクラスにのみ適用される場合、影響は最小限です。
トラブルシューティングの質問
変換が適用されていません
一般的な原因:
- 間違ったクラス名:
@ModifyClass
の値が正確に一致することを確認 - 間違ったメソッドディスクリプタ:
methodDesc
パラメータを確認 - クラスが読み込まれていない: 変換前にクラスがロードされることを確認
ClassCastExceptionが発生します
これは通常、以下を意味します:
CallbackInfo.returnValue
の型不一致- フックメソッドシグネチャの間違った型
- 互換性のない型への引数の変更
フックメソッドが呼び出されていません
確認事項:
- フッククラスがBuilderに渡されていますか?
- メソッド名とディスクリプタは正しいですか?
- ターゲットクラス名は正しいですか?
java.lang.VerifyError
これは変換されたバイトコードが無効であることを意味します。一般的な原因:
- 不正なバイトコード変更
- 型の不一致
- 無効なメソッドシグネチャ
変換後のパフォーマンス低下
変換が遅い場合:
- フックメソッドを簡素化
- フック内の高コストな操作を避ける
- 条件ロジックを使用して不要な作業をスキップ
- JVMプロファイラーでプロファイル
高度な質問
カスタムトランスフォーマーを作成できますか?
はい! トランスフォーマークラスを拡張するか、アノテーションの代わりにプログラマティックAPIを使用できます。
bytekinはメソッドのオーバーロードをサポートしていますか?
はい、パラメータ型と戻り値型を含む完全なメソッドディスクリプタを使用することでサポートしています。
同じクラスを複数回変換できますか?
はい、異なる変換を順次適用できます。
bytekinはスレッドセーフですか?
ビルド後、BytekinTransformer.transform()
はスレッドセーフで、複数のスレッドから同時に呼び出すことができます。
bytekinをJavaエージェントと一緒に使用できますか?
はい! bytekinはJavaエージェントとうまく動作します。エージェントのtransform()
メソッド内で使用します。
移行とアップグレードに関する質問
他のバイトコードツールから移行するにはどうすればよいですか?
概念は似ています:
- ターゲットクラスを定義
- 変換アノテーション付きフックメソッドを作成
- トランスフォーマーをビルド
- 変換を適用
コードを変更せずにbytekinをアップグレードできますか?
はい、bytekinは下位互換性を維持しています。アップグレード前に常にリリースノートを確認してください。
ライセンスと法的質問
bytekinはどのライセンスの下にありますか?
bytekinはApache License 2.0の下でライセンスされています。
bytekinを商用プロジェクトで使用できますか?
はい! Apache 2.0は商用利用を許可しています。
bytekinを使用する場合、コードをオープンソース化する必要がありますか?
いいえ、Apache 2.0はコードのオープンソース化を要求しません。ライセンス通知を含めるだけです。
コミュニティに関する質問
バグを報告するにはどうすればよいですか?
GitHub Issuesページでバグを報告してください。
どのように貢献できますか?
貢献は歓迎します! 貢献ガイドラインについてはGitHubリポジトリを参照してください。
どこで助けを得ることができますか?
- ドキュメントを確認
- GitHub Issuesを検索
- 例を確認
まだ質問がありますか?
質問がここで回答されていない場合:
次のステップ
- 例を探索する
- ベストプラクティスを確認する
- トラブルシューティングを確認する