Javaで開発された業務システムのドキュメントが失われ、「どこから手をつければいいのかわからない」という状況に直面している担当者は少なくありません。特に、EJBやStrutsで構築された10年以上前のシステムは、設計書が存在しないまま現役で稼働しているケースが多く、改修や移行の際にリバースエンジニアリングが不可欠な選択肢となっています。
本記事では、Javaのリバースエンジニアリングの進め方について、工程ごとに具体的な手順と注意点を解説します。JD-GUIやCFRといったJava専用の逆コンパイルツールの特性から、Spring Bootへのモダナイゼーション時に陥りがちな落とし穴、法的リスクの回避方法まで、実務で使える知識を体系的に整理しました。外注検討の判断軸についても触れていますので、ぜひ最後までお読みください。
▼全体ガイドの記事
・Javaのリバースエンジニアリングの完全ガイド
Javaのリバースエンジニアリングとは

Javaのリバースエンジニアリングとは、コンパイル済みのバイトコード(.classファイルやJARファイル)から、元のソースコードに近い形を復元し、システムの仕様・設計・業務ロジックを解析するプロセスです。Javaはコンパイル後も比較的高い抽象度のバイトコードが残るため、他のネイティブバイナリ言語と比べて解析しやすい特性があります。
他言語との違い・Javaバイトコードの特性
Javaのリバースエンジニアリングが他言語と大きく異なる点は、バイトコード(.class形式)というJVM向けの中間表現が存在することです。C言語やC++がネイティブバイナリにコンパイルされるのとは異なり、Javaのバイトコードにはクラス名・メソッド名・型情報が残っているため、JD-GUI、CFR、Procyon等の専用逆コンパイラを使えば、元のソースコードに非常に近いJavaコードを自動生成できます。
ただし、「比較的復元しやすい」ということは、同時に「悪意ある第三者にも解析されやすい」ということでもあります。そのため、商業アプリケーション特にAndroidのAPKファイルには、ProGuardやR8による難読化が施されていることが多く、難読化後のバイトコードでは変数名やクラス名が一文字の記号に置き換えられ、解析難易度が大幅に上昇します。
主な用途(レガシー移行/脆弱性診断/仕様書復元)
Javaのリバースエンジニアリングが実務で活用される場面は大きく3つあります。第一はレガシーシステムのモダナイゼーションです。EJB(Enterprise JavaBeans)やStrutsで構築された2000年代の業務システムは、現在でも多くの企業で稼働していますが、開発者の退職・文書の散逸によってブラックボックス化が進んでいます。こうしたシステムをSpring Bootへ移行する際に、リバースエンジニアリングで業務ロジックを復元することが増えています。
第二は脆弱性診断です。自社Javaアプリケーションのセキュリティ監査や、オープンソース製品の改変状況確認(ライセンスコンプライアンス)において、バイトコードレベルでの解析が必要になります。特に、OSSライブラリのバイトコードを解析して不正改変や禁止ライセンスの混入を確認するユースケースは、企業のコンプライアンス担当者から関心を集めています。第三は仕様書復元です。設計書が存在しないシステムの全体像を把握し、新システム開発の要件定義に活用するケースで、LOC(行数)あたり数十円の費用感で実施できます。
Javaのリバースエンジニアリングの6工程

Javaのリバースエンジニアリングを成功させるには、場当たり的に逆コンパイルツールを動かすだけでは不十分です。目的の明確化から成果物化まで、体系的な6つの工程を踏むことで、後工程の手戻りを防ぎ、質の高いアウトプットを得ることができます。
1. 対象選定・目的明確化
最初の工程では、解析対象のJavaシステムの全体像を把握し、プロジェクトの目的を明確に定義します。対象がJARファイルかWARファイルかEARファイルかによって、解析アプローチが変わります。また、解析の目的が「仕様書復元」なのか「脆弱性診断」なのか「モダナイゼーション前の業務ロジック抽出」なのかによって、解析の深度と成果物の形式が異なります。
この段階で特に重要なのは、ProGuardなどによる難読化の有無を事前に確認することです。難読化が施されている場合は、解析工数が2〜3倍以上に膨らむ可能性があるため、見積もりの前提条件として必ず確認が必要です。また、Springなど大規模フレームワークを使用しているシステムでは、フレームワーク依存の設計意図(なぜこのBean定義になっているのかといった設計判断)が失われやすいため、フレームワークのバージョンやDIコンテナの設定ファイルも解析対象に含めることを検討します。
2. 解析環境・ツール準備(Java特化ツール)
Javaのリバースエンジニアリングに特化した逆コンパイラとして、JD-GUI、CFR(Class File Reader)、Procyonの3つが代表的です。JD-GUIはGUIベースで操作が直感的であり、手軽に.classファイルを可視化できます。CFRはコマンドラインで動作し、最新のJava構文(ラムダ式やswitch式など)への対応が優れており、バッチ処理に向いています。Procyonは内部構造の復元精度が高く、特にジェネリクスを多用したコードの解析に強みがあります。
これらの逆コンパイラは用途に応じて使い分けることが重要です。また、APKファイル(AndroidアプリのJavaバイトコードを含む)の解析には、apktools でリソースを展開した後、dex2jar でDEXファイルをJARに変換してからJD-GUIで開くというワークフローが標準的です。解析環境はインターネットから切り離した専用端末を用意し、解析過程をログとして残すことで、後述の法的リスク回避にも役立ちます。
3. 静的解析(逆コンパイル・クラス構造の把握)
静的解析では、実際にプログラムを実行せずに、コードの構造・クラス間の依存関係・メソッドの呼び出し関係を解析します。逆コンパイルツールで生成したJavaコードをIDEにインポートし、クラス図やシーケンス図を自動生成することで、全体アーキテクチャの俯瞰が可能になります。EclipseやIntelliJ IDEAには、デコンパイル済みのコードから自動でUMLダイアグラムを生成するプラグインが存在します。
Springフレームワークを使用したシステムでは、XMLベースのBean定義ファイルやアノテーション(@Service、@Repository、@Transactionalなど)から、DIコンテナの設計意図を読み取ることが重要です。ただし、フレームワークが隠蔽している処理(AOPによるトランザクション制御など)は静的解析だけでは把握しにくく、動的解析との組み合わせが必要になります。
4. 動的解析(デバッガ・実行トレース)
動的解析では、実際にJavaアプリケーションを起動し、実行時の振る舞いをデバッガやプロファイラでトレースします。JVMにはJDWP(Java Debug Wire Protocol)というデバッグプロトコルが標準で組み込まれており、リモートデバッグ接続を使えば実行中のプロセスにアタッチして変数の状態やスタックトレースをリアルタイムで観察できます。
特にEJBのトランザクション境界やStrutsのActionクラスの遷移を追跡する際は、ログ出力を増やしたデバッグ用環境を別途構築し、実際のビジネストランザクションを流しながら挙動を記録する手法が有効です。Wiresharkを使ったネットワークトレースと組み合わせることで、外部システムとのI/F仕様も同時に把握できます。動的解析は静的解析では見えなかった「実際に使われているコードパス」と「デッドコード(未使用機能)」を明確にする上で欠かせない工程です。
5. 抽象化(Design Recovery:実装→設計→仕様)
抽象化工程では、静的・動的解析で得られた実装レベルの情報を、設計レベル・仕様レベルへと段階的に抽象化します。具体的には、逆コンパイルで得られたJavaコードをベースに、業務フローチャート・クラス設計書・データモデル(ER図)・画面遷移図へと変換していきます。この工程がリバースエンジニアリング全体の価値を決定づける最も重要なフェーズです。
Javaシステムの抽象化で特に難しいのは、「コードが何をしているか(How)」は把握できても、「なぜそのロジックになっているか(Why)」がコードからは読み取れない点です。例えば、特定の条件分岐に業務上の意味がある場合でも、変数名が難読化されていたり、コメントが存在しなかったりすると、その意図を解析者が正確に理解することは困難です。このWhyを補完するためには、業務部門の担当者へのヒアリングやドメインエキスパートの協力が不可欠です。
6. 成果物化(仕様書/新システム設計への接続)
最終工程では、抽象化した設計情報を成果物として文書化します。成果物の粒度は発注時に明確に合意しておくことが重要で、「単純なフローチャート」「業務仕様書(画面・DB設計含む)」「新システム開発に直接使える詳細設計書」の3段階によって費用と期間が大きく異なります。
Javaシステムをモダナイゼーションする場合(例:StrutsからSpring Boot、EJBからSpring Frameworkへの移行)、成果物の詳細設計書が新システムのAPI定義・クラス設計・DB設計の直接のインプットとなります。この段階で「現行機能のすべてを移植するか、不要な機能(過去の遺物)を棚卸して省略するか」の判断を行い、モダナイゼーションの範囲を確定させることが、後工程の効率化と費用の最適化につながります。
Javaのリバースエンジニアリングにおける固有の注意点

Javaの解析において技術的難易度を大きく左右する固有の要素があります。事前にこれらを把握しておくことで、プロジェクト計画の精度が上がり、予期しないコスト超過を防ぐことができます。
典型的な失敗パターン:Springフレームワーク依存の落とし穴
Springフレームワークを使ったシステムで最もよく見られる失敗は、「コードは読めたが業務ルールの意図が分からず、移行後にバグが多発する」というケースです。Springは依存性注入(DI)やアスペクト指向プログラミング(AOP)によって、業務ロジックとインフラ処理が分離されていますが、この分離がむしろ解析者にとって「どこに何の処理があるか」を分かりにくくします。
EJBシステムの解析では、CMT(コンテナ管理トランザクション)の境界がアノテーションやXML設定に隠蔽されているため、トランザクション制御ロジックを見落とすリスクがあります。また、StrutsのActionクラスはサーブレットと業務ロジックが密結合しているため、逆コンパイル後のコードがスパゲティ状になりやすく、解析者にとっても保守担当者にとっても読みにくい状態になります。このような複雑性を過小評価して工数見積もりをすると、プロジェクト後半で大幅な手戻りが発生します。
ProGuardによる難読化への対処と限界
AndroidアプリのAPKに含まれるJavaバイトコードは、ProGuardやR8による難読化が標準的に施されています。難読化後のコードでは、クラス名がa.b.cのような意味のない記号になり、メソッド名もa()・b()・c()と変換されるため、逆コンパイル自体は成功してもコードの意味を解読することが格段に難しくなります。
対処法としては、ProGuardのマッピングファイル(mapping.txt)が入手できる場合はそれを使って元の名称に復元する方法が最も効果的です。マッピングファイルが存在しない場合は、実行時のログ出力や例外スタックトレースを手がかりに、意味のあるクラス名を推定・付与する作業(リネーミング)が必要になります。この作業は非常に時間を要するため、難読化されたAPKの解析費用は通常の非難読化コードの解析と比べて2〜4倍になるケースが多いです。
法的リスクの回避とコンプライアンス対応

Javaのリバースエンジニアリングを実施する前に、法的リスクについて正確に理解しておくことが重要です。特にOSSのライセンスコンプライアンス確認でバイトコード解析を行う場合、著作権法の要件を満たした手順を踏むことが企業リスク管理の観点からも求められます。
クリーンルーム手法の実務運用
平成30年(2018年)の著作権法改正(第30条の4)により、非享受目的(仕様書復元・セキュリティ調査・マルウェア解析など)のリバースエンジニアリングは原則として合法化されました。ただし、ソースコードの無断複製や競合製品への転用は依然として著作権侵害となります。
著作権侵害リスクを確実に回避するための手法がクリーンルーム手法です。解析チーム(Dirty Room)と開発チーム(Clean Room)を完全に分離し、解析チームが作成した仕様書(機能・アルゴリズムのみを記述し、元コードの表現は含まない)のみを開発チームに渡して新システムを開発させます。両チームの間には法務担当者を配置し、仕様書に著作権保護対象の表現が混入していないかを検査する体制が理想です。この手法はIBM BIOS互換製品を開発したフェニックス・テクノロジーズの事例で有効性が実証されています。
非享受目的の立証と記録管理
著作権法第30条の4の適用を受けるためには、「非享受目的」であることを立証できる記録を残すことが重要です。具体的には、解析専用のパソコンを用意して解析作業を実施すること、解析過程をレポートとして記録すること、そして解析した情報をプログラムの実行による享受(ゲームのプレイ、映像の視聴など)ではなく技術的分析に使用したことを示す文書を整備することが有効です。
OSSライセンスのコンプライアンス確認でJavaバイトコードを解析する場合は、特に記録の整備が重要です。GPLやLGPLのライブラリが自社製品に不正に組み込まれていないかをバイトコードレベルで確認する作業は、コンプライアンス上の正当な目的として認められますが、そのプロセスと目的を文書化しておくことで、第三者からの疑義に対して明確に説明できます。
外注 vs 内製の判断軸

Javaのリバースエンジニアリングを自社で実施するか外注するかは、プロジェクトの規模・緊急度・社内技術リソースによって異なります。以下の判断軸を参考に、自社の状況に合った選択をしてください。
内製が向いているケースと条件
内製が適しているのは、自社にJava経験が豊富なシニアエンジニアがいる、解析対象が比較的小規模(数千行〜1万行程度)、業務ロジックの詳細を知る担当者が社内にいる、という条件が揃っているケースです。セキュリティ上の理由からソースコードを社外に持ち出せない場合も、内製が必要になります。ただし内製の場合でも、JD-GUIやCFRといったツールの習熟に時間がかかるため、少なくともパイロットフェーズは試算以上の工数がかかることを見込んでおく必要があります。
外注が向いているケースと選定ポイント
解析対象が大規模(数万行以上)、EJBやStrutsなど専門知識が必要なフレームワークが絡む、ProGuardによる難読化が施されている、という場合は外注が合理的です。外注先を選ぶ際は、Javaの解析実績(特にモダナイゼーション案件)が豊富か、クリーンルーム手法を自社プロセスとして確立しているか、成果物の粒度と品質基準を事前に明示できるか、の3点を確認することをお勧めします。
費用目安として、ソースコード解析による仕様書復元はLOCベースで30万円(4,000行まで)が基本料金となり、超過分は1行あたり50円程度が相場です。Springなど複雑なフレームワークを使用したシステムや、難読化が施されたAPKの場合はこの単価に割増係数をかける必要があります。モダナイゼーション全体(リファクタリング〜リビルド)では2億〜5億円以上の投資規模になるケースも珍しくなく、リバースエンジニアリングはその前段階の調査コストと位置づけるのが適切です。
まとめ

Javaのリバースエンジニアリングは、バイトコードという中間表現の存在により、C言語などネイティブバイナリを扱う言語と比べて解析の出発点が高く、JD-GUI・CFR・Procyonといった専用ツールで比較的高品質な逆コンパイルが可能です。一方で、ProGuardによる難読化やSpringフレームワークの設計意図の喪失、EJB/Strutsシステムの業務ロジックの複雑さなど、Java固有の難しさも存在します。
成功のカギは、目的と成果物粒度の明確化(工程1)、適切なツール選定(工程2)、静的・動的解析の組み合わせ(工程3・4)、業務部門との連携による抽象化(工程5)、そして法的リスクを管理したクリーンルーム体制(工程6)にあります。特に古いJavaのEJB/Struts製業務システムのSpring Bootへのモダナイゼーション案件では、設計書が失われているケースが多いため、リバースエンジニアリングが最も現実的な出発点となります。外注する場合は、Java案件の実績・クリーンルーム体制・成果物基準の3点を必ず確認してください。
▼全体ガイドの記事
・Javaのリバースエンジニアリングの完全ガイド
株式会社riplaでは、IT事業会社出身のプロフェッショナルが「Impact-Driven型支援」を通じて、プロダクトやシステムの納品・提供を目的とせず、お客様と同じ目線で、事業成果の達成をゴールとして、高品質なDX/開発支援をいたします。

また「Boxシリーズ」による、受発注管理・在庫管理・配送管理・業務システム・生成AI・SaaS・マッチングサイト・EC・アプリ・LINEミニアプリなどの標準機能の高速開発と、AI駆動開発の独自フレームワーク「GoDD」を活用することで、低コスト・短期間でのスクラッチ開発を実現いたします。

もし、システム開発やプロダクト開発に関するご要望がございましたら、お気軽にお問い合わせください。
・サービス概要資料のURLはこちら >>>
・お問合せページのURLはこちら >>>
・お役立ち資料のURLはこちら >>>


株式会社ripla 代表取締役CEOとして、システムパッケージ活用、システム開発、データ分析、生成AI活用、SaaS開発、アプリ開発、EC構築など、幅広い領域で企業のDX推進と事業成長を支援している。IT事業会社出身のプロフェッショナルが集う株式会社riplaにおいて、「Impact-Driven型支援」を掲げ、単なるシステム納品にとどまらず、クライアントと同じ目線で事業成果の実現に向けた伴走支援を行う。早稲田大学卒業後、ラクスル株式会社、LINEヤフー株式会社にて事業開発やDX推進などに従事した後、株式会社riplaを創業。
