メモの日々


2005年05月23日(月) [長年日記]

  • 最近はテストとか環境設定とかばかりしている。
  • テストしているプログラムはバグだらけでパフォーマンスもかなり悪い。実装に問題があるわけだけれど、実装のお願いの仕方にも大いに問題がある感じ。

[shell] シェルをviモードで使うようにする

シェルのコマンドライン編集にはemacsモードを使っていたが、emacs使いではないのでviモードに変更してみた(viが得意なわけでもないのだけれど)。

bashの場合は .inputrc ファイルに

set editing-mode vi

と書き、tcshの場合は .cshrc ファイルに

bindkey -v

と書けばいいみたい。

[java] 旧バージョンのJVMでも動くようにコンパイルする

J2SE 5.0 環境でコンパイルしたClassファイルをJRE 1.4 環境へ持っていったら動かなかった。

javacのマニュアルを見ると

javac -target 1.4 Example.java

のようにすればよさそうだがこれだと

javac: ターゲットリリース 1.4 がデフォルトのソースリリース 1.5 と競合しています。

というエラーになってしまった。そこで

javac -target 1.4 -source 1.4 Example.java

と指定したらコンパイルでき、生成されたClassファイルはJRE 1.4 環境でも動作した。

でも、マニュアルを読んでいると-bootclasspath オプションと -extdirs オプションも必要そうなことが書いてある。ブートクラスパスと拡張機能ディレクトリってなんだ?

[java] ブートストラップクラスと拡張機能クラス

についてはクラスの検索方法というドキュメントに説明があった。

ブートストラップクラスは、Java 2 プラットフォームを実装しているクラスです。ブートストラップクラスは、jre/lib ディレクトリの rt.jar と他のいくつかの JAR ファイルに格納されています。これらのアーカイブは、システムプロパティ sun.boot.class.path に格納されているブートストラップクラスパスの値によって指定されます。このシステムプロパティは参照専用なので、直接修正しないでください。

拡張機能クラスは、Java プラットフォームを拡張するクラスです。拡張機能ディレクトリ jre/lib/ext 内の .jar ファイルはすべて拡張機能と見なされ、Java 拡張機能フレームワークを使ってロードされます。拡張機能ディレクトリ内でどこにも属さないクラスファイルは、見つけることができません。これらのファイルは、.jar ファイル (または .zip ファイル) 内に含まれている必要があります。拡張機能ディレクトリの位置を変更するためのオプションはありません。

ふむ。

[java] -bootclasspath オプションと -extdirs オプションの使いどころ

まだよくわかんないんだけど。ブートクラスパスはブートストラップクラスの位置を指定するパス、拡張機能ディレクトリは拡張機能クラスが存在するディレクトリ、ということだろう。

で、J2SEのバージョンアップに伴ってブートストラップクラスや拡張機能クラスの仕様が変わっている可能性があって旧バージョン用のプログラムがコンパイルできないことがあるからその場合はjavacの -bootclasspath オプションや -extdirs オプションを使って旧J2SEに付属しているクラスを指定する、と理解すればいいのかと思ったけど、「機能リリースおよびメジャーリリース (1.3.0、1.4.0、5.0 など) では、ソースレベルの上位互換性は保証されるが、下位互換性は保証されない」ということでソースレベルの上位互換性が保証されるならそういうことではないのか。

もう一度javacのマニュアルを見直す。

Java 2 SDK の javac は、デフォルトでは、Java 2 SDK のブートストラップクラスに対してコンパイルを行うので、Java 2 SDK ではなく JDK 1.4 のブートストラップクラスに対してコンパイルを行うように指定する必要があります。これは、-bootclasspath および -extdirs を使って指定します。この指定を行わないと、1.4 VM には存在しない Java 2 プラットフォーム API に対応したコンパイルが行われるため、プログラムの実行時に障害が発生することがあります。

「実行時に障害」と言っているのでバイナリの互換性のことを言っているのだろう。-target オプションで1.4向けのバイナリを作るように指定しても、それだけでは1.4に付属しているブートストラップクラスや拡張機能クラスと組み合わせたときに正しく動作しないことがあるってことだなあ。なんでそうなるのだ?わからん。

とにかく、マニュアルを読むと上に書いたような

javac -target 1.4 -source 1.4 Example.java

じゃダメで

javac -target 1.4 -source 1.4 -bootclasspath jdk1.4.2/lib/classes.zip Example.java

としなければいけないように思われる。でも単にこれだと

致命的エラー: クラスパスまたはブートクラスパスでパッケージ java.lang を検出できません。

とエラーになってしまいコンパイルできない。コンパイルするにはJDK1.4.2に付属するclasses.zipが必要そうだ。そうだとするとJ2SE5.0だけでは1.4向けのバイナリは作れないってことになってしまう。

5.0と1.4の両方の環境をいじれれば調べられそうだけれど、手元にはないからよくわからないまま終わり。

[java] -bootclasspath オプションと -extdirs オプションの使いどころ (2)

単純にこういうことかなあと思った。

「-target 1.4 -source 1.4」というオプションは付けるが「-bootclasspath」オプションは付けずにコンパイルすると、ソース中に5.0で新たに追加されたブートストラップクラスを利用している箇所があってもコンパイルできてしまうと。この場合、1.4環境にClassファイルを持っていくと動かないと。だから、5.0で追加されたブートストラップクラスや拡張機能クラスを使っていないことが分かっている場合は「-bootclasspath」オプションは付けなくても大丈夫と。

試せてないから分からないけど、正しい気がする。

やること

  • リンク元のスリム化
  • tDiaryバージョンアップ
  • FSWikiバージョンアップ
  • オーブンレンジ用べんり棚
  • ブラウンの安い電動歯ブラシ買う
  • 蛍光灯を捨てる