私はJavaのコードだけは書けないプログラマ、だったのだが、最近Javaを使わせられるヤバそうな仕事につくことに。Javaと言えばSpring Frameworkです。フレームワーク部分を無駄にXMLで書くやつね。
その前に。
まあしょうがないので最初にHelloWorld、と思ったのですが、これが動かない! なんでHelloWorldが動かないのよ、と。
package main; public class Main{ public static void main(String[] args){ System.out.println("Hello"); } }
これをMain.javaという名前で作って、
- javac Main.java
- java Main
- エラー: メイン・クラスMainが見つからなかったかロードできませんでした
ふざけてるんですかこのクソ言語は。いや見つけろよ。そこにあるでしょ。
悩みに悩みました。
Javaのpackage文は厳密なもので、パッケージ名として表現されたシンボルとそこに至るディレクトリ構造は完全に一致していなければなりません。これはpackage文にかぎらず、ファイル名はクラス名と一致していなければならない。そんなクソ仕様でみんなプログラム書いてたのかかわいそうに。
正解はプログラムの中ではなく、外にあったのだ。
- mkdir main
- cp Main.class main/
- java main.Main
- Hello
- あるいは java -cp .. main.Main
- Hello
とりあえずこのアイサツには深く感動…しかしどうなんだこれ。ディレクトリ名がどうだろうと関係ないんじゃないのかな。そもそもMain.javaがあるディレクトリが/some/path/to/main とは限らないじゃん? main.bakになったりmain2になったりするじゃん? それで動かないのはアレじゃん? ヤバすぎる。
だいたい拡張子(.class)まで書くと実行できないとか。ファイル名指定でいいじゃないですか。単にjavaコマンドが拡張子が.classだったときにそれを省けばいいだけの話でしょう? classは予約語でクラス名にはならないし。もともとクラス名に厳密さはなくて、これ↓は動くんだから。スラッシュをドットとみなすのね。Windowsではバクスラをドットとみなすのかな。
- java -cp .. main/Main
- Hello
しかもですね、Javaはたいていのモジュールで階層構造が深い。無駄に深すぎる。おかしい。
package jp.foo.bar.baz.love.respect.and.love.modulename;
みたいな。そしてですね、さらにひどいのが、探すファイルを一意にしたいんだと思いますが、ドットをドットと見なさない。ドットを表現するのがスラッシュ、そしてスラッシュは表現できない…とにかく、どの階層も真のディレクトリじゃないといけない。結果、途中にファイルがないディレクトリが無駄にできて、無駄に使いにくくなる。
- mkdir jp.foo.bar.baz.love.respect.and.love.modulename
- cp Main.class jp.foo.bar.baz.love.respect.and.love.modulename/
- java jp.foo.bar.baz.love.respect.and.love.modulename.Main
- エラー: メイン・クラスjp.foo.bar.baz.love.respect.and.love.modulename.Mainが見つからなかったかロードできませんでした
- mkdir -p jp/foo/bar/baz/love/respect/and/love/modulename
- cp Main.class jp/foo/bar/baz/love/respect/and/love/modulename/
- java jp.foo.bar.baz.love.respect.and.love.modulename.Main
- Hello
こんなに嫌な気持ちになったのはいつ以来だろう。この仕様はさすがに…Python, JavaScript, Golangみたいに外部モジュールに名前空間を汚されない言語を好んできた自分には受け入れられない。このへんはRubyもたいがいだったけど、Javaは輪をかけてひどい。これじゃ安心してプログラムできないじゃないか。
まあ短い単発のプログラム書くときはpackage文を書かざるべし、ってことなんでしょうね。そもそも単発の短いプログラムはJavaでは書かないという説も。
Githubでファイルを見るときに、中間ディレクトリに子ディレクトリが1個しかない場合に省かれて、末端までワンクリックで行けるようになってるじゃないですか。あれJavaへの対応なんだなと思いましたね。一個一個たどってく単純作業ってムカつきますもん。時間はタダじゃない。
あんな感じでJavaを快適に使えるファイルシステムはあるんだろうか。ディレクトリが構造になってたらアウトだよねこれ。S3みたいにフラット構造でデリミタを切り替えられ、デフォルトはデリミタなし。chdirは単なるprefix指定。基本はやっぱりデリミタなしでlsとfindが同じ動作をする感じかな。つーかjavaコマンドの探し方が悪い。
まあ.jarを作ればいいんだろうな。packageを見て自動でzipの中のファイル名を決めて格納してって、mainがあるクラスを見つけたらmanifestに書けばjava -jarでファイル名で実行できる。mainのリストを出して切り替えるユーティリティとかも簡単に作れるよね。そのくらいならどっかに転がっているだろう。
いまのところ、希望はprintfが0x0なとこくらいかな。