Javaの重複コードを高速に検知する ccd-java を agentic coding で錬成した
仕事でちょっと重複コードが問題になったのと、Twitterで見かけた similarity-ts に触発されてJavaの重複コードを検知するライブラリを作ってみました。
TS書いてる人、頼む claude-code にこのプロンプト流して similarity-ts を試してみてほしい。
— mizchi (@mizchi) 2025年6月25日
「similarity-ts は typescript のコード重複を検知するツールです。cargo install similarity-ts して、similarity-ts . でローカルファイルのコード重複を確認し、リファクタの計画を立ててください。」… https://t.co/BbTXeRBSDZ
ライブラリはこちら
せっかくなので違うアルゴリズムで作ってみました。 またRustでやろうかと思ったのですがどうもRustのインストールがうまくいかなかったのでJavaで書き直しました。(もちろんClaude君が)
ChatGPTのDeepSearchでコードクローンの検知アルゴリズムの論文を検索して要約させ、筋が良さそうなものをJavaで実装させました。 gradleのセットアップ以外は完全にClaudeによるコードです。あんまり真面目にテストしてないですが、手元ではそこそこ精度良く良く動いていそうです。
java環境がないと動かないので、気が向いたらもう少しポータブルな形で実行できるようにしてみようと思います。
以下 Claude 君による説明
ccd-java: 高速Java向けコードクローン検出ツール
はじめに
コードクローン(重複したコード断片)は、ソフトウェアプロジェクトにおける一般的な技術的負債です。保守の悪夢、一貫性のないバグ修正、肥大 化したコードベースにつながる可能性があります。ある程度の重複は避けられませんが、クローンを特定し管理することは、コード品質を維持する上 で極めて重要です。
ccd-javaは、Java プロジェクト専用に設計された高速でスケーラブルなコードクローン検出ツールです。最先端の SourcererCC アルゴリズムを実装し、数百万行規模の巨大なコードベースでも効率的にクローンを検出します。
ccd-java の特徴
🚀 圧倒的な高速性能
- 100万行のコードを30秒以内で解析
- 並列処理により利用可能なすべてのCPUコアを活用
- 転置インデックスを使用したメモリ効率的な設計
🎯 高精度な検出
- 3つのタイプのクローンを高精度で検出
- コード構造を理解するトークンベース解析
- 誤検出を減らすスマートフィルタリング
🎨 開発者に優しい出力
コードクローンのタイプ
ccd-java は、類似性に基づいてコードクローンを3つのタイプに分類します:
Type 1: 完全一致クローン
空白やコメントを除いて同一のコード断片。
// ファイル: UserService.java public User findUser(String id) { User user = userRepository.findById(id); if (user == null) { throw new UserNotFoundException(id); } return user; } // ファイル: CustomerService.java (Type 1 クローン) public User findUser(String id) { User user = userRepository.findById(id); if (user == null) { throw new UserNotFoundException(id); } return user; }
Type 2: 名前変更クローン
変数名やメソッド名が異なるだけで構造的に同一のコード。
// ファイル: OrderValidator.java public boolean validateOrder(Order order) { if (order == null || order.getItems().isEmpty()) { return false; } return order.getTotalAmount() > 0; } // ファイル: InvoiceValidator.java (Type 2 クローン) public boolean validateInvoice(Invoice invoice) { if (invoice == null || invoice.getLineItems().isEmpty()) { return false; } return invoice.getTotalSum() > 0; }
Type 3: 修正クローン
一部の文が追加、削除、または変更された類似コード。
// ファイル: FileProcessor.java public void processFile(String path) { File file = new File(path); if (!file.exists()) { logger.error("File not found: " + path); return; } String content = readFile(file); processContent(content); } // ファイル: DocumentProcessor.java (Type 3 クローン) public void processDocument(String path) { File file = new File(path); if (!file.exists()) { logger.error("Document not found: " + path); notifyUser("Document missing"); // 追加 return; } validatePermissions(file); // 追加 String content = readFile(file); processContent(content); updateCache(path, content); // 追加 }
SourcererCC アルゴリズムの仕組み
ccd-java が実装する SourcererCC アルゴリズムは、以下の革新的な手法により高速性を実現しています:
1. トークンベース解析
生のテキストやAST構造を比較する代わりに、コードをトークン列に変換:
元のコード:
public int calculateSum(int a, int b) { return a + b; }
トークン列: [public, int, $, (, int, $, ,, int, $, ), {, return, $, +, $, ;, }]
識別子が $ に正規化されることで、Type 2 クローンの検出が可能になります。
2. 低頻度トークンによる転置インデックス
レアなトークン(出現頻度下位20%)のみを使用してインデックスを構築:
トークンインデックス:
"calculateSum" -> [Block1, Block15, Block92] "validateOrder" -> [Block23, Block67] "processPayment" -> [Block34, Block88, Block101]
これにより、必要な比較回数が劇的に削減されます。
3. スマートフィルタリング技術
プレフィックスフィルタリング
トークンを頻度順にソートし、プレフィックスが十分に一致しない場合は早期終了:
ブロックA: [processPayment, validateCard, checkBalance, return, if, int, $]
ブロックB: [processRefund, cancelOrder, updateStatus, return, if, int, $]
↑ 異なるプレフィックス = 早期終了
トークン位置フィルタリング
完全な計算の前に類似度の上限・下限を推定:
上限 = min(|A|, |B|) / max(|A|, |B|) 下限 = max(0, |A| + |B| - 総ユニークトークン数) / max(|A|, |B|)
上限が閾値を下回る場合、そのペアは完全にスキップされます。
実際の使用例
典型的なJavaプロジェクトでの ccd-java の使用方法:
# 基本的な使用法 - 現在のディレクトリを解析 $ java -jar ccd-java-1.0.0.jar # 70%の類似度閾値で特定のプロジェクトを解析 $ java -jar ccd-java-1.0.0.jar /path/to/spring-project -t 0.7
出力例:
╔════════════════════════════════════════════════════╗ ║ Code Clone Detection for Java ║ ║ Powered by SourcererCC ║ ╚════════════════════════════════════════════════════╝ Analyzing Java files in: /path/to/spring-project Similarity threshold: 70% ✓ Found 2,341 Java files → Tokenizing files... ✓ Tokenized 8,234 code blocks → Building inverted index... ✓ Index built successfully → Detecting clones... ╔════════════════════════════════════════════════════╗ ║ Code Clone Detection Results ║ ╠════════════════════════════════════════════════════╣ ║ Found 156 clone pairs ║ ║ Type 1 (Exact): 34 ║ ║ Type 2 (Renamed): 89 ║ ║ Type 3 (Modified): 33 ║ ╚════════════════════════════════════════════════════╝ High Priority Refactoring Candidates: ┌─────────────────────────────────────────────────────┐ │ 1. service/UserService.java:145-201 ←→ service/CustomerService.java:89-145 │ Similarity: 96% (Type 2) │ ████████████████████████░ │ │ 2. utils/StringHelper.java:45-78 ←→ common/TextUtils.java:23-56 │ Similarity: 91% (Type 1) │ ███████████████████████░░ └─────────────────────────────────────────────────────┘
Claude Code による Agentic Coding
このプロジェクトは、Anthropic の Claude Code を使用して開発されました。Claude Code は、AIエージェントが自律的にコーディングタスクを実行する新しい開発パラダイムを実現します。
開発プロセス
- 初期実装: SourcererCC 論文を解析し、アルゴリズムの詳細な実装計画を作成
- 言語選択: 最初はRustでの実装を検討しましたが、JavaParserなどの成熟したエコシステムを活用するためJavaに変更
- アーキテクチャ設計: パッケージ構造、データフロー、並列処理戦略を自動的に設計
- 実装: 複数のファイルにまたがる複雑な実装を一貫性を保ちながら実行
- ビルドシステム移行: MavenからGradle(Kotlin DSL)への移行を自動実行
- 国際化: すべての日本語コメントとドキュメントを英語に翻訳
- ライセンス対応: SourcererCCのGPL-3.0ライセンスを適切に継承
Claude Code は、これらすべてのタスクを対話的に実行し、エラーを自己修正し、コードの一貫性を保ちながら、プロダクション品質のソフトウェア を生成しました。
まとめ
ccd-java は、あらゆる規模のJavaプロジェクトにエンタープライズグレードのコードクローン検出機能を提供します。最先端のSourcererCCアルゴリ ズムを実装することで、速度、精度、使いやすさの完璧なバランスを実現しています。
小さなライブラリから巨大なエンタープライズアプリケーションまで、ccd-java はコードの重複を特定し排除するのに役立ち、よりクリーンで保守しやすいコードベースへと導きます。
今すぐ ccd-java を使い始めて、重複のないコードベースへの第一歩を踏み出しましょう!
ccd-java は GPL-3.0 ライセンスのオープンソースソフトウェアです。カリフォルニア大学アーバイン校の Sajnani らによる SourcererCC アルゴリズムに基づいています。
このプロジェクトは https://claude.ai/code を使用して開発されました。