日付:1998/1/29
Powerbook2400+Visual Cafe:さてそれは1998年1月14日のことであった。実家に帰ってみるとテーブルの上に私宛の小包が届いている。あけてみれば待ちに待ったVisual Cafe for JAVAである。これさえくれば。。。と考えるのは本当は甘いのであるが、両親との会話もそこそこにパッケージを大事に抱えて私はアパートに戻ってさっそくインストールを始めた。
ホームページにのせる文章のほうはそこそこできていたので、「あとはこのリンク集だけできれば、人に見せられるのに」と数日思ってフラストレーションをためていた。これでようやくホームページ公開にこぎつけられるかもしれない、と思えば心がはやるという物である。
アプリケーションを山ほどインストールした後で、MRJ2.0をインストールしてみた。ひょっとしたら今度はJDKのjavacが動くのではないか、と思ったからである。ところがぎっちょん。現実は常に冷徹である。また例のメッセージがでて立ち上がってくれない。まあいいや。もうjavacに頼る必要はないのだ。
次にはVisual CafeについてきたNetscape Communicatorを使って、今までできていたアプレットを使って画面表示の試験をしてみた。ところがぎっちょん。やはり結果はNetscape Navigator3.0と同じである。うーん。これはNetscape社の製品は本格的にあきらめなくてはならないようだ。今までInternet Explorer < Netscape Navigatorと思ってきた私だが、ここで「Microsoft社の軍門に下る」必要があるかもしれない。
などとやっていたらいつの間にか結構時間がたってしまった。いけない。本題はVisualCafeでのアプレット開発ではないか。。。と気を取り直して。
さてではさっそくマニュアルを読んで。。。とツアーを始めたが、まもなくマニュアルが異常に読みにくいことに気がついた。初めての分野であるから、言葉も概念も見慣れないためわかりにくいのかな。。と思ったがそうでもないようだ。訳もちょっとおかしいのかもしれないが、たぶん原文が妙なのだろう。たとえばJavaBeansとのところは何度読んでもなんのことやらさっぱりわからない。
というわけでまずちょっとだけツアーをやって、よーし。これでできるぞ、と思って作りかけのLink Browerを写してコンパイルしよう、と思ったらあっさり壁にぶつかった。うむ。やはりマニュアルは尊重しなくてはならない、と思ってまたツアーに戻り、、という試行錯誤を何度かやったあげく、なんとかコンパイルに成功した。。(コンパイラが動かなくなってからチェックなしにずいぶんプログラムを追加したので山のようなコンパイルエラーがでたが。おまけにいくつか「警告」は表示されていたのであるが、あっさりと無視した)
Applet Viewerで動かしてみると、なんとなく動いているようではある。しかしスクロールリストから要素をクリックして選ぶ処理がうまくいかない。どうもイベント処理のメソッドに飛んでいる気がしない。
えーいしょうがない。さっき無視した「警告」が効いているのかもしれない、と思ってよくよく警告をみてみれば、AWTの各コンポーネントに対するイベント処理のところで警告がでている。曰く「この方法は古い」のようなことを言ってくる。
確かに前述の参考書に載っているイベント処理の仕方には多少疑問をもっていたのである。一例を挙げればこうだ。これはスクロールリストをクリックしたとき(要素を選んだとき)のイベント処理のリストだが(TIP #515)
public boolean handleEvent(Event evt)
{
if(evt.target instanceof List)if(evet.id == Event.LIST-DESELECT).{//Event処理のコードがかかれるという感じなのだが、これでは、evt.targetのクラスを確認しているだけで、名前を確認していない。ということは一つのアプレットに複数のスクロールリストがあったときにその区別が付かないではないか。おまけにこのサンプルプログラムではhandleEventメソッドを完全にオーバーライドしているので、何がおこるかわかったもんじゃない。(superを呼べばいいのだろうが)確かにこのサンプルプログラムは、この機能だけをしめせばいいのであるから、これでいいのかもしれないが、ちょっとはた迷惑な感じである。
でもってまた先ほどの「とても読みにくい」Visual Cafeのマニュアルに戻るわけだ。そこでみてみると、どうもJDK1.1からイベント処理の仕方が変わったらしい。なるほど確かにこの方法じゃあな。。しかしバージョン番号が0.1上がるだけで、いきなりイベント処理を変更するなんて言う大規模な変更をしてもいいものだろうか?これはまだJAVAが開発の初期段階にあることを意味する物かもしれない。
さて例によってマニュアルを読んだだけでは、VisualCafeがイベント処理をどうやってくれるのかさっぱりわからない。しょうがないから、実際に「イベント処理の自動コード作成」機能を使ってみるか。。。
そこである事実に気がついた。イベント処理の自動コード作成機能を使おうと思ったら、まずその対象となる各オブジェクトをVisual Cafeの画面上で定義せねばならないらしい。(実は後でそうでもないことに気がついたが)なんということだ。またあの画面定義の苦労をせねばならんとは。
そうはいっても今度は各パラメータを変更した結果をほぼリアルタイムに画面上で確認できるのでらくは楽である。また例によって例のごとくの試行錯誤をくりかえしながら、、なんとか画面ができあがった。
さて自動作成されたプログラムをみてみると、確かに山のようなコードができている。便利というかなんというか。。。はたしてこのコードをどのように変更していいものかどうか?Appletの中にあるinit()メソッドの中ですべて画面の要素が定義されていて、とてもこのままでは使えた物ではない。init()はほとんどメソッドの呼び出しだけにしたい。この方法を見つけるのにまたもや結構な時間を費やした。(実はマニュアルの中に該当の記述があることに後で気がついた。しかしそれでもマニュアルをまじめに読んでみよう、という気がおきないほど、マニュアルは読みにくいのである)
さてこれでようやく振り出しに戻った、という感じである。ようやく本来の目的であるイベント処理を自動作成させてみると。。。ちゃんと動くではないか。例によって大量のコードが自動作成されているが(そして例によってこれをどうなおして良くて、どうなおしていけないか、マニュアルの記述は破壊的に読みにくいが)とりあえず動くわけである。めでたし。めでたし。
さてそこで一息ついて、、、今まで脇に置いてあった難関に再び直面することになった。すなわち日本語の表示である。今までなんとなくデバッグを繰り返していたが、依然として日本語はちゃんと表示されないのである。
javacが動かなくなる前になんとなく、URL経由のファイル読み込みがうまくいっているらしい、ことは確認していた。(この点に関するJavaの機能はたいしたものだ。ほとんど数行でサーバー上のファイルが、ローカルファイルと同じような手続きで読み込めるのである)ところがその表示となるとうまくいかないのである。前のバージョンでうまくいった「Javaメッセージへの出力」もやってみたが、うまくできない。(未だにあのときなぜうまくいったかわからない)そこからの戦いは結構長かった。
まずNiftyserveのJAVAフォーラムに行って、同じような質問がないかどうかチェックしてみた。するとやはりどこにも同じような質問をするような人はいるとみえて「ネットワーク経由でファイルを読み込むにはどうすればいいのでしょうか」という質問と「ネットワーク経由の通信で日本語のやりとりがうまくいきまません。」というのがあった。
両方とも私の質問とは微妙に重なり、微妙にずれているのである。後者の質問はほとんど参考にはならなかった。前者の質問は、ファイル読み込みの参考になった。しかし質問者が答えを得て「ありがとうございました。ちょっと変更したら日本語の表示もできました。。」と書いているのはいいが、肝心の「どう”ちょっと変更した”か」は書いていないのである。これでは参考にならない。
サンプルプログラムがないかデータライブラリをあさってみたり、、としばらくNiftyの中をさまよったあげく、一時はNiftyserveで先ほど「ちょっと変更したら」と書いていた人にメールを書いて教えを請おうかと思った。しかし書いた人がちゃんとメールを読んでくれる人とは限らないし。。。というわけでインターネットに答えを求めることにした。
私が日頃愛用しているサーチエンジンはyahooなのであるが、どうもここからではうまく検索できない。「JAVAでの日本語ファイル入出力」というトピックではYahooは検索できないし、JAVA関連ででてくるサイトを片っ端からあたるわけにもいかない。
というわけで全文検索型のサーチエンジンで探してみた。すると結構あるものである。いくつかの関連ページが見つかった。そしてわかったことは「JDK1.1からReader,Writerクラス(及びそれらのサブクラス)が追加されている。2バイト文字の読み込み、書き出しにはそれらを使用する必要がある」ということである。なるほどそういうことであったか、とさっそくInputStreamのクラスをReaderクラスのサブクラスに変更して。。。新しいクラスに変更したとたん、妙なバグがみつかったりもしたが、なんとかコンパイルエラーの山をのりこえてApplet Viewrで表示させてみると。。なんと日本語がちゃんと表示されているではないか!このときの感動はなかなかほかでは得難い物である。
さていよいよ作成したアプレットと、リンク先のデータをサーバー上においてテストする運びとなった。それまで使用していたテスト用のデータと、クラスをサーバーにアップロードして。。見事表示がされる。これで私はとてもご機嫌になった。
それから調子にのってlinkBrower用のリンクデータをがんばって定義した。自分がブックマークに登録しているサイトから選んだのであるが、あらためて自分が通常妙なサイトを訪れていることに気がついた。いやいや妙なことで感動している場合ではない。
さてほかのホームページのコンテンツと一緒にアップロードして、、、さっそく使ってみようと思ったら妙なことに気がついた。ローカルハードディスクにおいてテストしたときはなんの問題もなかったのだが、サーバーにおいてみるとなんとファイルの後半がきちんと読み込めていないではないか。。
がびーん。まだまだ先は長かったか。それからまた一日つぶしていろいろなことをやった。まず元データの順番を少し変更してみたが、同じようなところでファイルが切れる。うーん。これは。。
正直言ってここまであれやこれやの問題を解決してきたが、これはもういやになった。読み込むバイト数を勘定してみるとだいたい1000バイトでこけているようだ。しかしこの1000という数字に何か意味があるかどうかわからない。
と言ってもこのまま公開するのもなあ。と思って最後の(そして結構最低の)手段をとった。読み込むファイルを分割したのである。手動で「だいたい1000バイト以内」に区切って読み込む。
人間プログラミングで疲れてくるとこういうばかげた解決手段をとるものである。そしてだいたいこういうときにやった解決手段は後からみると、「なんだこれ」ということで、お払い箱になる。
従ってプログラミングでもなんでも、正当な手段を用いて問題を解決するのでなければ問題の解決にはならない。まるで道徳の授業の内容のようだが、私のプログラミングに関する経験からするとこれは正しい。
さて今であればこういったことも言える。しかしとにかく当時私はまがりなりにもLink Browerができあがったのでご機嫌であった。さっそくサーバーにアップロードしてテストするとなんとか動く。めでたしめでたしということで忘れようとした。
ところがそこでまた別の問題につきあたったのである。今回作ったものは動くのはいいがあまりにも制約が多いアプレットになってしまった。世の中の過半数を占めるNetscapeのユーザーには私のページが読めないのである。しかもこれが簡単に解決されるとは思えない。
となれば次善の策として、HTMLで書いたリンク集も併せて設置することが必要である。これであれば「好きな人はJavaでみてください。ちょっと便利かもしれませんよ」と言うことができるわけである。そこでまたもや疲れている私は妙な解決方法をとることになった。アプレット専用のリンクのデータを読み込んでアプレットがHTMLのファイルを吐き出すような仕組みを作ったのである。
これは一見うまくうごくように思えた。実際プログラム自体はちゃんと動いてブラウザでちゃんと表示できるHTMLファイルを吐き出したのである。しかし私はここではたと詰まった。この「ファイル出力機能をどこから起動したらいいんだろう?」
アプレットにボタンをつければ、別にファイルの出力などしたくない人が、妙なJavaメッセージが出力されるのをみて驚くことになる。(アプレットからはローカルにファイル出力ができないので、Javaメッセージとして出力するようにしたのである)。だいたい誰もが使用しないボタンなどつけるのはいやだ。するとたとえば既存のリストとかボタンに変なコールバックをつけるか。。それにしてもなんとなくスマートでない。
まあいいや。そんなにリンク集の更新は多くないだろうから、そのたびにコードを変更してHTMLファイル出力関数を呼んだり呼ばなかったりすればいいや。ということで、本質的な問題から目をそらしてまたもや問題を先送りしようとしたのである。
しかしながらこの解決方法はものの2日ももたなかった。リンク集の更新が私が思ったよりも頻繁に行われることが判明したのである。おまけにLinkBrower専用のファイルの更新は結構面倒だということがわかった。さらに調子にのって追加していくといつ1000バイトを越えるかもしれないのである。だいたい人間が1000バイトを越えるかどうかチェックするなんて言うのは本末転倒だ。数を数えるなんてのはコンピュータのほうが人間の100000000倍も得意なのに。
さてそこで前から薄々感じていた解決方法に直面することになった。LinkBrower専用のファイルをマスターとしてそこからHTMLファイルを吐き出すのではなく、HTMLをマスターとして、そのデータを読み込んでLinkbrowerに表示させてはどうか?だいたいデータを2カ所に持つとろくなことはないのである。同じ意味をもつデータであれば一カ所に集めるべきだ。
なぜいままでこの可能性をうすうす感じながら実行しなかったか?いままでのファイル読み込みルーチンは基本的にreadLineで一行ずつ読み込んでデータを処理していた。ところがどうもHTMLファイルというのは、一行になにがはいるか、についてはほとんど意に介していないように思える。いくつかの設定を一行にかこうが、何行かに分けて記述しようが結果は同じでなくてはならない。すると、HTMLファイルを読み込んで処理するためにはreadLineをすてて、一文字ずつ読み込んでいく処理に変更しなくてはならない。
私はreadLineを非常に愛していたので、そこから離れるのはつらかった。しかしこの際贅沢はいっていられない。またもや参考書をひっくり返し、あれこれサンプルプログラムを作ったりして。。。とにもかくにもHTMLファイルから読み込みLinkBrowerに表示することに成功したのである。
しかしながらここで私はまた別の問題から目をそらしているのである。例の1000バイトの問題である。しかしこの時点でなんとなく私は開き直っていた。どうせたいていの人はHTMLバージョンの方を読むだろう。多少ファイルが切れていたってどうってことはない。わかる人は、まあコンセプトだけで「ふーん」と思ってくれるだろう。
それと私はファイルが切れることに関していくつか自分に対するいいわけをみつけていたのである。1000バイトが問題だと思っていたが、ローカルファイルを読み込む場合でもファイルがとぎれることがあることがわかった。しかも内容をちょっと変えるとファイルがとぎれなくなったりするのである。ということはきっとこれは私のせいではない。Javaの環境のせいだ。こうやってすぐ問題をソフトウェア環境のせいにするのはろくなプログラマではない証拠だ。しかし私が使用していたMRJ2.0はまだPreviewバージョンであるし、、バグが残っているからPreviewというのである。そうだそうだそうに違いない。
というわけであっさりとその問題を忘れることにした。そして自分の身勝手な理論を裏付けるためにInternet Explorer 4.0をダウンロードした。これにはMicrosoftのJavaがついていて、そちらでテストしてみようと思ったのである。
結構な時間をかけた後になんとかセットアップに成功して。。。またどきどきしながらサーバー上のリンク集にアクセスしてみると、ほーらみろ。ファイルは切れずにちゃんと読み込める。わたしのせいじゃないもんね。と喜んではいられなかった。なんとまた画面が変わっていることに気がついたのである。Netscapeほどへんではないが、やっぱりどことなく変である。。。しかしもういい。一応使えるから文句は言うまい。
さてちょっと修正してローカルの環境で試験をしよう、と思ったら今度はローカルのファイルが読み込めなくなっている。MRJではSecurityが甘いので、ローカルのハードディスク上にあるファイルでも、URL経由でなんとなくネットワーク先にあるかのように書いておけば読み込めたが、MicrosoftのJavaではその手は通じないようだ。うーん。えーい。もう何もかも忘れた。とりあえずこれでフィックスだ。
しかしなんだな。確かに世間で言われているとおり"Write once, Run everywhere"というのはまだまだ遠い先の話で(あるいは永遠に到達できない目標で)"Write once, Debug everhwhere"というのが正しい姿で、このままいつまでも続くのではないだろうか。。これがJavaが確固たる標準になるのか、あるいはMicrosoftの独占的な天下が来て終わるのかはっきりしないが。。。
というわけでとりえあず私はリンク集をJavaで作るという目的を達成した。。そして重要なことはなんとなく文章をJavaでブラウズするにはどうするか。。というイメージが明確になってきた。HTMLファイルを読み込んで処理もできることがわかったし、AWTの使い方も少しはなれた。これから新しいプログラムに取りかかるわけだが。。。問題はコンテンツの作成にやたら時間がかかることに気がついたことだ。このjavaDiaryの執筆には対象となるLinkbrowerの作成と同じくらいの時間を要している。私は失業中で日長暇な身分のはずだが、なぜかこのままでは時間がなくなってしまうような感じがする。しかし好きなことを好きなだけやる、なんていう贅沢をできるのは本当に短い間だけだ。がんばって取り組むことにしよう。
(1998/1/29)
注釈
Microsoft社の軍門に下る:なぜかアップル社を目の敵にしている日経新聞が好きな表現。MicrosoftとApple社の協定(Microsoftからの資金提供、相互クロスライセンス、Intenet Explorerを標準ブラウザとする、Mac上のMS-Officeの開発5年間保証)があったときに、なぜか日経新聞は「Apple社、Microsoft社の軍門に下る」と表現していたらしい。本当に軍門に下っていたらこんなに苦労しないと思うのだが。本文に戻る
バージョン番号が0.1上がるだけ:この時私はこのように考えたが、JDK1.1からJDK1.2の間の変更というのは、1.0→1.1とは比べ物にならないくらい大きかった。実のところウィンドウ関係のクラスはごそっと変更になったのである。(コンパチビリティはとれるようなっていたものの)本文に戻る
ちゃんと表示:たぶんちゃんと表示されているのだと思う。今のバージョンでもテキストエリアにはいったん文字化けした表示がされて、一瞬後にまともな表示に戻る。こういうものなのか、あるいは私のプログラムが悪いだけなのか。たぶん本当のところを突き止めるべきなのだろうが、とりあえず表示されている、ということでアマチュアプログラマは満足してしまうのである。不思議なことだがinternetExplorerに付属のMicrosoftのJavaVMではそういった書き換えもなくちゃんと表示されるのである。
しかし同時に私はここで「プログラムは2バイト文字をどうやって1バイトの文字と区別しているのか?」という問題に突き当たることになった。考えてみればファイルの中身はバイトがならんでいるだけだ。1バイトか2バイトってどうやって区別しているんだろう?というわけで探求はまだ続く。。。はずなのだが日曜プログラマはまたもやここでこの問題を先送りしてしまうのであろう。本文に戻る
正当な手段を用いて問題を解決するのでなければ問題の解決にはならない(トピック一覧):これは事実から帰納的に導き出した結論であるから、尊重に値するだろう。わざわざここに書いてもおそらくすぐ忘れることであるが。本文に戻る
問題をソフトウェア環境のせいにするのはろくなプログラマではない証拠だ:(トピック一覧)今のところこの経験則はたいてい正しい。本文に戻る
わたしのせいじゃないもんね:InternetExplorer3.0とMRJ2.0の組み合わせでもうひとつ気がついていた問題として、リンク先の画面が新しいウィンドウに表示されない、というものがある。(プログラム上はちゃんと指定しているにもかかわらずである)これもExplorer4.0で実行したらちゃんと新しいウィンドウに表示されるようになった。本文に戻る
"Write once, Debug everhwhere":この言葉の発明者は定かではない。本文に戻る