ikuo’s blog

育児やエンジニアリングについて

Javaの重複コードを高速に検知する ccd-java を agentic coding で錬成した

仕事でちょっと重複コードが問題になったのと、Twitterで見かけた similarity-ts に触発されてJavaの重複コードを検知するライブラリを作ってみました。

ライブラリはこちら

github.com

せっかくなので違うアルゴリズムで作ってみました。 またRustでやろうかと思ったのですがどうもRustのインストールがうまくいかなかったのでJavaで書き直しました。(もちろんClaude君が)

ChatGPTのDeepSearchでコードクローンの検知アルゴリズムの論文を検索して要約させ、筋が良さそうなものをJavaで実装させました。 gradleのセットアップ以外は完全にClaudeによるコードです。あんまり真面目にテストしてないですが、手元ではそこそこ精度良く良く動いていそうです。

java環境がないと動かないので、気が向いたらもう少しポータブルな形で実行できるようにしてみようと思います。

以下 Claude 君による説明


ccd-java: 高速Java向けコードクローン検出ツール

はじめに

コードクローン(重複したコード断片)は、ソフトウェアプロジェクトにおける一般的な技術的負債です。保守の悪夢、一貫性のないバグ修正、肥大 化したコードベースにつながる可能性があります。ある程度の重複は避けられませんが、クローンを特定し管理することは、コード品質を維持する上 で極めて重要です。

ccd-javaは、Java プロジェクト専用に設計された高速でスケーラブルなコードクローン検出ツールです。最先端の SourcererCC アルゴリズムを実装し、数百万行規模の巨大なコードベースでも効率的にクローンを検出します。

ccd-java の特徴

🚀 圧倒的な高速性能

  • 100万行のコードを30秒以内で解析
  • 並列処理により利用可能なすべてのCPUコアを活用
  • 転置インデックスを使用したメモリ効率的な設計

🎯 高精度な検出

  • 3つのタイプのクローンを高精度で検出
  • コード構造を理解するトークンベース解析
  • 誤検出を減らすスマートフィルタリング

🎨 開発者に優しい出力

  • ターミナルでの美しいASCIIアート表示
  • 見やすいカラーコード化された結果
  • 複数の出力形式(テキスト、JSONCSV
  • ナビゲーションしやすい相対ファイルパス表示

コードクローンのタイプ

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エージェントが自律的にコーディングタスクを実行する新しい開発パラダイムを実現します。

開発プロセス

  1. 初期実装: SourcererCC 論文を解析し、アルゴリズムの詳細な実装計画を作成
  2. 言語選択: 最初はRustでの実装を検討しましたが、JavaParserなどの成熟したエコシステムを活用するためJavaに変更
  3. アーキテクチャ設計: パッケージ構造、データフロー、並列処理戦略を自動的に設計
  4. 実装: 複数のファイルにまたがる複雑な実装を一貫性を保ちながら実行
  5. ビルドシステム移行: MavenからGradle(Kotlin DSL)への移行を自動実行
  6. 国際化: すべての日本語コメントとドキュメントを英語に翻訳
  7. ライセンス対応: SourcererCCのGPL-3.0ライセンスを適切に継承

Claude Code は、これらすべてのタスクを対話的に実行し、エラーを自己修正し、コードの一貫性を保ちながら、プロダクション品質のソフトウェア を生成しました。

まとめ

ccd-java は、あらゆる規模のJavaプロジェクトにエンタープライズグレードのコードクローン検出機能を提供します。最先端のSourcererCCアルゴリ ズムを実装することで、速度、精度、使いやすさの完璧なバランスを実現しています。

小さなライブラリから巨大なエンタープライズアプリケーションまで、ccd-java はコードの重複を特定し排除するのに役立ち、よりクリーンで保守しやすいコードベースへと導きます。

今すぐ ccd-java を使い始めて、重複のないコードベースへの第一歩を踏み出しましょう!


ccd-javaGPL-3.0 ライセンスのオープンソースソフトウェアです。カリフォルニア大学アーバイン校の Sajnani らによる SourcererCC アルゴリズムに基づいています。

このプロジェクトは https://claude.ai/code を使用して開発されました。