OracleのDavid BuckさんによるBytecode Verification

毎週金曜日に開催している社内勉強会ですが、今週は久々の外部ゲストとしてOracleのDavid Buckさんにお越しいただきBytecode Verificationについてお話しいただきました。

f:id:takezoe:20160903121051j:plain

Buckさんは今年もサンフランシスコで開催されるJavaOne 2016で3本のセッションに登壇されるそうで、そのうちの1セッションの内容を、しかも日本語でお話しいただけるという大変貴重な機会でした。

Bytecode Verificationが必要な理由

Bytecode VerificationはJavaVMが不正なバイトコードを検出するための機能ですが、普段その存在を意識することがほとんどないのではないかと思います。しかし実際のところ、以下のように不正なバイトコードに遭遇し得るシチュエーションには様々なものがあります。

Javaは古いコンパイラコンパイルされたクラスファイルでも動作させることができるのですが、バイトコードを操作するツールやライブラリがバイトコードに仕様の相違を理解せずに操作してしまいバイトコードが壊れてしまうというケースもあるのだそうです。

結論

結論としては非常にシンプルで「Bytecode Verificationはデフォルトで有効なので無効にしないでください」とのこと。

パフォーマンス面の理由からBytecode Verificationを無効にしているオープンソースプロジェクトもありますが、現代のコンピュータではほぼ無意味なので、余計なトラブルを防ぐためにも開発環境であろうとプロダクション環境であろうとBytecode Verificationを無効にするべきではないとのことでした。

壊れたバイトコードを読み込んだ場合、Bytecode Verificationが有効であればわかりやすいエラーメッセージが出るのですが、無効になっているとVMがクラッシュしたりします。こういった場合はコアダンプを見てもクラスファイルが壊れているのかVMのバグなのかの切り分けが非常に難しく、仕事柄いろいろとご苦労されてきた苦悩がありありと伝わってきましたw

日頃Javaを使っていてもJavaVMの中身まで触れる機会は中々ないので大変勉強になりました。マニアックな話題だったとは思うのですが、学びあり、笑いありの楽しい発表でしたので、JavaOne 2016に参加される方は是非Buckさんのセッションに足を運んでみていただければと思います。

豆知識

ちなみにデフォルトでは-Xverify:remoteが有効なのですが、以下のオプションを指定できます。

デフォルトがremoteなのは元々JavaはAppletでの利用が想定されており、アプリケーションのクラスファイルはリモートサーバから読み込んで実行することが前提だった時代の名残なのだそうです。Javaの歴史を感じますね〜。