Java回顧録 〜独白: 僕は全ての事をJavaから学んだ〜

先日Javaのコードを3年振りくらいで書いてみたら、無性にJavaについて振り返ってみたくなった。Javaの誕生当時をリアルタイムで経験した僕にとってJavaは感慨深いものであり、多くのことをJavaから学び、僕を成長させてくれた原点でもある。

僕とJavaとの関わりはJavaがまだOakと呼ばれていた頃から始まる。1994年の暮れの頃だったと思う。Oakで書かれたWebブラウザはWebRunnerと呼ばれていて、両者はほとんど一体だった。会社の上長からこれを使って携帯情報端末機器を開発することになったから、秘密裏に調査しておくようにと突然指示された。後になって知ったことだが、Oakは家電などの組込み系を想定して開発されたもので、当時Sunは日本の多くのメーカに呼びかけてOak を普及させようとしていたようだ。

その頃のインターネット事情というのは、Mozilla(Netscape)が登場してまもなくのころであり、その前進のブラウザであるMosaicが広く普及していて、新聞などではインターネットとモザイクが同義語として使われていたくらいだ。Googleもなければ、Wikipediaもなく、Flashさえなく、ブログも登場していない。ブラウザ上で動くものといったらMozillaのスプラッシュ画面でGodzillaが火を噴くパラパラアニメーション程度。国内のWebサイトも大学や大企業などが主で非常に数が少なかった。今では信じられない実に質素な世界だ。

そんな中、Oakが登場したのである。当初、OakとWebRunnerはオープンソースだった。FirstPersonというサイトから誰でも自由にダウンロードできたと記憶している。FirstPersonというのはOakを開発したGreenProjectの後の名前であり、Sunのエンジニア達による少数精鋭の組織である。Oakはその後、商標の問題からJavaという名前に変わり、WebRunnerはHotJavaという名前に変わった。

上長からは、キミなら興味を持つんじゃないか、とのことだったので、どんなシロモノなのか興味津々で動かしてみた。Linuxもまだ一部のマニアが使っている程度だった時代であり、動作はSun Workstation上に限られた。あたりまえであるが、Javaに関する文献・書籍等はもちろん一切なく、ソースコードとサンプルプログラムを読み解くしかない。

Javaを調査して半月くらい経ったとき、上長からJavaは今後主流になるものか、あるいは、このプロジェクトで終わるようなものなのか、どう思うかと聞かれた。僕は、これはインターネットに新たな革命をもたらす凄いものだ、一企業のものではなく、人類の財産になると答えたことを今でも記憶している。世間知らずの生意気な若造が随分なことを言ったという感じだったが、僕にとってそのくらい衝撃的なものだった。

Javaがどんなものかを技術的に解説したJ.GoslingらのWhite Paperも秀逸だった。まだ、ドラフトだったが、一般に、論文ではないこの手の冊子は事実と乖離して風呂敷を広げすぎていたり、単に企業の宣伝だったり、胡散臭さが感じらるものだが、このWhite Paperは読むだけで勉強になったし、技術に対する真摯さが伝わってきて、非常に感銘を受けた。恥ずかしながら、そのときはGoslingの名前も知らなかったが、これは本物だと直感した。

初期のJavaJavaで書かれたクラスライブラリを除くC言語のネイティブ部分は5万行程度であったと思う。一人で全体を把握できるギリギリの規模だが、まとまったドキュメントがなく、ソースコードを毎日じっくりと丹念に読んでいった。パズルを解くような作業が連日続いたが、コードは宝の山だった。しかも、まるで一人の人によって書かれているかのように統一的で美しかった。全体を理解するのに1ヶ月くらいかかったが、とても充実した日々だった。開発者の情熱というか息遣いがコードの行間から感じられ、開発者と直接対話しているかのような錯覚さえ覚えた。

ソフトウェア技術者として知っておくべきことが、そこには全てあった。しかも、これらがほぼスクラッチからの実装になっている。記憶を頼りに当時の概要を列挙してみよう。

いわゆるスタックマシンであるが、実行時にバイトコードを書き換える(quick_*命令)など、メソッド探索などの高速化に工夫がされていた。バイトコード自体は目新しさはなかったが、変数の型に対応したバイトコードが定義されている。関数コール時のスタックの使い方やnativeコード間のデータ授受など実装がかなり勉強になった。デバッガはまだなかったが、デバッグのための情報が埋め込まれる仕組みが開発途上という状態で存在していた。一方、コードを読み始めた頃はスレッドもこのバイトコード上で実装されていると期待していたが、残念ながらそうではなかった。

マーク&スイープ方式のシンプルなGCであったが、Cスタック上のオブジェクトのスキャンなどConservativeな実装のノウハウを具体的に知ることができた。ネイティブコードの中にSparcアセンブル言語で記述されたコードが若干含まれていたが、関数コールの際のWindowレジスタをマークする部分だった。インテル系だったらset_jmp()でレジスタの値をローカル変数上に退避すればよい技法である。

  • スレッド

スレッドはOSが提供するnativeスレッドではなく、アプリケーションレベルで実装されていた。従って、Java自身はマルチスレッドであるが、OSからみたらJava全体がシングルスレッドだった。JavaのスレッドはGreen Projectの名前から、green threadと呼ばれていた。システムがアイドル時間に裏でGCが起動する機構を読み取ったときはちょっと感動した。コードの理解には苦労したが、スケジューラを含めたスレッドの実装を把握することができ、大きな糧となった。

当時、スレッドは上級プログラマの対象であり、気軽に誰でも使えるというレベルのものではなかった。Javaによって言語機能としてスレッドサポートされ、一気に大衆レベルとして身近になったことは非常に画期的なことだった。

  • GUIツールキット

X11上のWidgetは使わず、Xlibレベルの最小限のネイティブコードがあり、それをJavaのクラスでラップして、その上にAWTがあった。Xlibはスレッドセーフではないため、至るところmutexの塊だった。

  • グラフィックエンジン

当初のAWTは実にシンプルだった。Xlibのdraw系APIの一部を単純にコールしていただけで、回転やスケーリング機能もなく、線幅も1しかなった。Javaアプリで太い線を描くのには苦労した。さらに、曲線はOvalしかなかったと思う。

コアの極一部がCで実装され、コンパイラ(javac)はJava自身で実装されているというブートストラップ方式のコンパイラJava自身でコンパイルするため実行速度が遅かったが、コンパイラの勉強にはうってつけのコードだった。後にIBMからJikesというC++で実装されたJavaコンパイラオープンソースでリリースされ、javacより非常に高速であったため、それが一時期、大変重宝した。

  • ネットワーク

それまでC言語でsocket関数を使ってゴリゴリとコードを書いていた僕にとって、数行でHTTPクライアントが書けてしまうHTTPConnectionクラスは斬新だった。しかもプラグイン可能なプロトコルハンドラによりアプリケーションに独自なURIが定義でき、その潜在的可能性に新たな視界が広がった思いがした。

コードを読んでいると至る所にArthur van Hoffという名前が登場している。Netnews(java.lang.com)でもArthurが大活躍していた。いろいろな質問に丁寧に回答していて、最後のお決まりの Have Fun!という言葉を必ず添えていて、好印象だった。

幸運にも、そのArthurにパシフィコ横浜で開催されたJavaOne(だったと思うが)でお目にかかることができた。貴重な時間の合間に講演者控え室で軽いミーティングを持った。体格のいいカッチリした真面目そうな男だった。僕らは組込系にJava を使うことを検討していたが、AWTが重かった。その懸念を伝えると、TinyAWTというものがある。それを使ったらどうかと提案された。TinyAWTはまだ公式には知られていなかったが、ソースを読んでいたのでその存在自体は知っていた。Arthurはそれを趣味で自分ひとりで2週間で作ったとあっさりと楽しそうに言ってのけた。真のハッカーだ。僕は、GoslingはJavaの生みの親であるが、育ての親はArthurであり、その貢献はGoslingより大きかったと思っている。

それから3ヶ月後くらいだっただろうか。そのArthurがSunを去るということを突然自らNetnewsにアナウンスし、Java界に大きな衝撃が走った。Javaは今後どうなるのか?ArthurはSunを去る理由として、Sunにも大企業病が蔓延り、スピード感がなく、やりいたいことが思うようにできなくなっている、Javaの可能性はもっともっと大きいもので、自分たちはそれを追求していきたい、Sunを退社するのはそのための英断だ、といったような趣旨の内容だったと思う。ArthurがいなくなってもJavaは本当に大丈夫なのか?多くの心配が寄せられた。そのような懸念にもArthurは丁寧に答えてくれた。Sunには信頼できる優秀な技術者が大勢いる、自分がいなくなっても何も心配することはない、大丈夫だ、問題ない、と。

Sunを去ったArthurたちはMarimbaというベンチャーを起し、Castanetというサービスを始めた。MarimbaではJavaの名付け親でもあるKim PoleseがCEOになった。彼女はSunでもリーダシップを発揮していたが、若き女性実業家として、おまけに美人ということでマスコミにももてはやされた。僕もCNNのインタビューで見たことがあるが、直接会ったという人からはハリウッドの一流女優のようだったと聞いた。

Marimbaは製品のネーミングを南米の楽器に統一していたが、CastanetはCast-a-Netであり、ネットにプログラムや情報をキャストするという実にうまいネーミングだ。Castanetはその意味通りプッシュ技術であり、クライアントにダウンロードしたJavaプログラムも最小限のオーバヘッドで更新することができるという優れものだった。一時期大きく注目されたが、残念ながら日の目を見ることなく消滅した。今ではネットワークが十分高速であり、組込み系でも、OS含めてアプリ丸ごとバージョンアップも簡単にできてしまう。今から思えば、結局、彼らの目指したものも最初から淘汰される運命にあったということなのかも知れない。

開発を進めていた携帯情報端末について、僕自身はその後、Javaによるアプリケーション開発を担当することになり、ブラウザの中でローカルアプリケーションとネット上のアプリケーションがシームレスに連携するようなフレームワークを開発し、メンバがそのフレームワーク上に個々のアプリケーションを開発するというものを作り、一定の成果を収めたものの、残念ながらプロジェクト自体は失敗に終わった。今では当たり前のものであるが、当時は斬新な発想であった。方向性は良かったが、あまりにも時期が早すぎたのである。

プロジェクトが終了した後も、まだJavaは面白かったし、経験も生かしたいという思いもあり、全く別の分野であるがJavaを使うというプロジェクトに飛び込み参加した。1年程度開発に没頭したが、世間的にもJavaが広く認知されるようになることと反比例して、JavaBeansが登場した頃には徐々に僕の中ではJavaに対する熱が醒めていった。

さらに、Javaはクライアントサイドでは思ったように発展しなかった。ブラウザ中のAppletの起動は遅いし、頻繁に落ちたりした。Java2Dのデモを見たときは感動したが、それがJavaだからということであり、多くのネイティブアプリがLinuxでもWindowsでも走るようになってきたし、Javaを使うことによる開発者メリットはあっても、エンドユーザのメリットはほとんどなかったのである。

一方、サーバサイドのJ2EEが登場したことで再び脚光を浴び、新たな新天地が開けたが、J2EEは複雑怪奇で巨大な化け物だった。僕にとって、もうそこにプログラミングの楽しさを見出すのは困難であった。

数年間くらいJavaから遠ざかっていたとき、JavaScriptの処理系を実装するという仕事が舞い込んだ。OSS採用には色々な意味でまだ慎重な風潮があったから、自力で作るしかないし、それが求められていた。恐らく、JavaJavaScriptの区別も付かないような人が、あいつならなんとなくできそうだという安易な人選だったに違いない。僕はといえば、正直、JavaScriptはよく知らなかったし、ノンプログラマが使うような取るに足らないつまらない言語と内心馬鹿にしていたくらいだ。趣味でLisp処理系をCで実装したことはあるので、まぁその程度だろうと高を括っていた。当時、JavaScriptに内部関数があることも知らなかったし、正規表現があることさえも知らなかった。そんな状態で、とりあえず、言語仕様であるECMA262規格書を読み始めたのである。それを読めば簡単にJavaScriptが分かると期待して。

ショックを受けた。書いてあることの意味がわからない。木は見えるけれど、森が見えないのである。書店に行き多量に並んでいるJavaScriptの本を見てみたけれど、どれも取るに足らない内容ばかりで、はっきり言ってしまえば、くだらないことしか書かれていなかった。ECMA262規格書から受けた、これは手強いぞ、という雰囲気が伝わるものは全くなく、単なるプログラミング入門的な本ばかりだった。

本で理解するなんて安易な方法が間違っていると気づき、かつてJavaソースコードを読んでいた時と同じように、来る日も来る日もECMA262規格書を読んでいった。しかし、そんな悠長に勉強しているような時間はない。スケジュールは非常にタイトであった。言語を理解していないのに、その処理系を実装するというアクロバティックな状況であったが、プログラムを書かない日々は苦痛でもあっため、とにかくコードを書き始めた。

トップダウン方式のパーサを作り、抽象構文木を直接評価して実行するコアのプロトタイプを2週間ほどで実装した。でも、これではダメだと気付いた。メモリ消費が多く、パフォーマンスも出ない。書いたものはすべて捨てて、バイトコード方式に切り替えた。パーサにはBisonを使った。そのときには、内部関数も正規表現の概要も理解している積りだった。

しかし、愚かにも内部関数がクロージャに繋がることを理解したのは、それからずっと後のことだった。関数がfirst classオブジェクトであるような言語ならばクロージャがあって当然であるが、馬鹿にしていたJavaScriptにまさかクロージャがあるとは思ってもみなかったのである。ECMA262規格書にはそんなご丁寧なことは書かれていない。ECMA262規格書というのは、数学に例えるならば、公理だけが羅列してあり、そこから推論規則により導出される定理については一切言及されていない、という難物ものである。定理こそ含蓄のある深い意味を持つものであるが、それは冗長であるから必要ないという、よそ者が近づき難い高尚さ(?)がある。無味乾燥な規格書でも理解を助けるためのinformativeな記述があるのが普通だが、それさえほとんどない。ちなみに、結果的に廃案になったが、Edition4では実行可能な仕様記述言語としてのMLによる定義が進められていた。MLを理解しているプログラマがどれほどいるだろうか。

そんな状況だったから、クロージャを実現しなければならなとわかった時には、既に実装がかなり進んでいた。スタックのアドレスが連続した古典的なスタックマシンをベースにしていたので、そこにクロージャの仕組みを入れるのは困難であり、壁にぶち当たってしまった。現状の仕組みを変えることなく、全く別のものを入れるという難問である。解はあるはずとは思うが、すぐには思いつかない。僕は、しばしばこのようなときには、解決すべき問題を頭に積め込み、後はそのことは考えずに放っておく、いわゆる寝かせておくという手段をとる。うまくいくときもあれば、いかないときもある。一つの問題に捕らわれていると袋小路に入ってしまい逆効果なのだ。解は何気ない時にふと見つかるものである。今回も幸運なことに、うまい方法が見つかった。

一方、正規表現OSSのPCREが利用できないかと検討していたが、ECMA262規格と動作が同じにならない部分があることがわかった。しかも、それは規格書の中の例として載っている正規表現で、間違っている方の動作になっているのである。PCREに手を入れるのは避けたかった。実用上はコーナーケースであるが、規格書ではそれは正しくないと敢えて明記されているのでる。しばらく途方に暮れたが、意を決してスクラッチから作ることにした。自分にそんな力があるだろうか?正直不安であるが、前に進むしかない。大学のとき勉強したオートマトンをちょっと復習して、パーサを実装し中間コードにコンパイルして規格書に記載されているアルゴリズムを実行する正規表現エンジンを2週間で作った。僕自身そんな短時間でできるとは思ってもみなかった。案ずるより産むが易しである。

開発はどうにか間に合い、製品に組み込むことができたが、JavaScript処理系など言ってみれば既に世の中にあるものであり、それと同じものを作ったところで、コードを書かない人から見れば、できて当たり前、その程度にしか思われない。しかし、それはそれでよい。他人にはできない、貴重な経験をさせてもらったわけだから。そして、真実を知らず、勝手につまらない言語と思い込んで馬鹿にしていたJavaScriptは今では大好きである。さらに、それ以前の自分とは異なる物の見方、視点、価値観などを得ることができた。プログラミングというのは、他に例えようのない唯一無二の特殊な内的活動だと思っている。そこから何を得るのかは人それぞれに異なる。

懐かしくてついついいろいろなことを書き過ぎたようだ。いずれにしても、あのときJavaと出逢ったことが、僕の技術者としてのその後の方向性を大きく決定付けたと感じている。人との出会い、本との出会い、技術との出会い、これらは気づかないと何事もなかったように過ぎ去ってしまうが、とてもとても大切なことなんだ。